hooks

package
v0.3.49 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package hooks installs and uninstalls the per-agent integrations that drive questmaster's state tracker. Each Installer owns its agent-native files and removes only Questmaster-managed state on uninstall.

Index

Constants

View Source
const AssetTag = "v1"

AssetTag is the tag value written into agent config files alongside hook entries we own. The tag identifies entries the installer is allowed to remove on uninstall. Bumping this value requires reviewing the round-trip behaviour for every agent's config format.

View Source
const QuestmasterSidecarVersion = "phase2-v2"

QuestmasterSidecarVersion is the marker version emitted by the Pi activity-sidecar contract that shells out to `questmaster hook pi`.

Variables

View Source
var ScriptTemplate string

ScriptTemplate is the embedded shell-script body. The `__AGENT__` placeholder is substituted with the agent name at install time.

Functions

func AgentList

func AgentList() []string

AgentList returns the canonical agent identifiers (sorted) for agents that have installable hooks. Derived from defaultInstallers so it always matches the set NewManager registers. Exported so cmd/hooks.go can render status output without instantiating a Manager.

func RenderScript

func RenderScript(agent string) string

RenderScript fills the embedded template for a given agent. Exposed for installer implementations (and tests).

Types

type ClaudeInstaller

type ClaudeInstaller struct {
	// Home is the resolved Claude config directory (~/.claude or
	// $CLAUDE_CONFIG_DIR). Override only in tests.
	Home string
}

ClaudeInstaller manages the Claude Code hook surface. Writes the script to ~/.claude/hooks/questmaster-state.sh and merges hook entries into ~/.claude/settings.json — Claude Code does not load hooks from settings.local.json, so writing there is a no-op.

func NewClaudeInstaller

func NewClaudeInstaller(home string) *ClaudeInstaller

NewClaudeInstaller resolves the Claude config directory. Pass an explicit home for tests; pass "" to honour $CLAUDE_CONFIG_DIR / $HOME.

func (*ClaudeInstaller) Install

func (c *ClaudeInstaller) Install() error

Install implements Installer.

func (*ClaudeInstaller) InstallWithOptions

func (c *ClaudeInstaller) InstallWithOptions(opts InstallOptions) error

InstallWithOptions installs Claude hooks with optional dry-run logging.

func (*ClaudeInstaller) Name

func (c *ClaudeInstaller) Name() string

Name implements Installer.

func (*ClaudeInstaller) Status

func (c *ClaudeInstaller) Status() Report

Status implements Installer.

func (*ClaudeInstaller) Uninstall

func (c *ClaudeInstaller) Uninstall() error

Uninstall implements Installer. Removes questmaster hook entries from settings.json (identified by command path) and deletes the installed script. Other user-managed hooks are left alone.

type CodexInstaller

type CodexInstaller struct {
	Home string
}

CodexInstaller manages the Codex hook surface. Writes the script to ~/.codex/hooks/questmaster-state.sh, merges tagged entries into ~/.codex/hooks.json, and records Codex's required trusted_hash state in ~/.codex/config.toml.

func NewCodexInstaller

func NewCodexInstaller(home string) *CodexInstaller

NewCodexInstaller resolves $CODEX_HOME / $HOME. Pass an explicit home for tests; pass "" to honour $CODEX_HOME / $HOME.

func (*CodexInstaller) Install

func (c *CodexInstaller) Install() error

Install implements Installer.

func (*CodexInstaller) InstallWithOptions

func (c *CodexInstaller) InstallWithOptions(opts InstallOptions) error

InstallWithOptions installs Codex hooks with optional dry-run logging.

func (*CodexInstaller) Name

func (c *CodexInstaller) Name() string

Name implements Installer.

func (*CodexInstaller) Status

func (c *CodexInstaller) Status() Report

Status implements Installer.

func (*CodexInstaller) Uninstall

func (c *CodexInstaller) Uninstall() error

Uninstall implements Installer. Removes tagged entries from hooks.json, removes questmaster's managed trust block from config.toml, and deletes the installed script. Untagged user hooks and config keys are left alone.

type InstallOptions

type InstallOptions struct {
	DryRun bool
	Log    io.Writer
	Now    func() time.Time
}

InstallOptions configures hook install side effects.

type Installer

type Installer interface {
	// Name is the agent identifier used in CLI arguments and hook payloads.
	Name() string
	// Install writes/updates hooks on disk. Idempotent: re-running must
	// produce a byte-identical config file when nothing changed.
	Install() error
	// Uninstall removes only files or entries the installer owns. Leaves other
	// user-managed hooks/config alone.
	Uninstall() error
	// Status reports the current install state. Never returns an error;
	// installer-internal problems surface in Report.Detail.
	Status() Report
}

Installer is the per-agent contract. Implementations are registered with Manager via RegisterDefault.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager orchestrates a fixed set of installers.

func NewManager

func NewManager() *Manager

NewManager returns a Manager seeded with the built-in installers.

func (*Manager) CheckCurrent

func (m *Manager) CheckCurrent(agents []string) (bool, []Report, error)

CheckCurrent returns false if any selected agent isn't Current. Used by `hooks install --check`.

func (*Manager) Install

func (m *Manager) Install(agents []string) error

Install runs Install for the named agents (or all if empty).

func (*Manager) InstallWithOptions

func (m *Manager) InstallWithOptions(agents []string, opts InstallOptions) error

InstallWithOptions runs installation with optional dry-run/logging.

func (*Manager) Names

func (m *Manager) Names() []string

Names returns the registered agent names in stable order.

func (*Manager) Register

func (m *Manager) Register(inst Installer)

Register adds an installer to the manager. Used by tests to inject stub installers rooted at temp directories.

func (*Manager) Resolve

func (m *Manager) Resolve(name string) (Installer, error)

Resolve returns the installer for the named agent.

func (*Manager) Status

func (m *Manager) Status(agents []string) ([]Report, error)

Status returns one Report per requested agent (or all if empty).

func (*Manager) UninstallWithOptions added in v0.3.32

func (m *Manager) UninstallWithOptions(agents []string, opts InstallOptions) error

UninstallWithOptions runs uninstallation with optional dry-run/logging.

type OpenCodeInstaller added in v0.3.36

type OpenCodeInstaller struct {
	// ConfigDir is the Questmaster-owned OpenCode config directory. Override in tests.
	ConfigDir string
}

OpenCodeInstaller manages Questmaster's OpenCode plugin bridge and role agents. It writes only Questmaster-owned files under Questmaster's private OpenCode config dir.

func NewOpenCodeInstaller added in v0.3.36

func NewOpenCodeInstaller(configDir string) *OpenCodeInstaller

NewOpenCodeInstaller resolves Questmaster's OpenCode config directory. Pass an explicit dir for tests; pass "" to use <QUESTMASTER_STATE_ROOT>/opencode.

func (*OpenCodeInstaller) Install added in v0.3.36

func (o *OpenCodeInstaller) Install() error

Install implements Installer.

func (*OpenCodeInstaller) InstallWithOptions added in v0.3.36

func (o *OpenCodeInstaller) InstallWithOptions(opts InstallOptions) error

InstallWithOptions writes the plugin bridge and role agent files. It is content-idempotent and preserves all other user-managed OpenCode config.

func (*OpenCodeInstaller) Name added in v0.3.36

func (o *OpenCodeInstaller) Name() string

Name implements Installer.

func (*OpenCodeInstaller) Status added in v0.3.36

func (o *OpenCodeInstaller) Status() Report

Status implements Installer.

func (*OpenCodeInstaller) Uninstall added in v0.3.36

func (o *OpenCodeInstaller) Uninstall() error

Uninstall implements Installer. Removes only Questmaster-owned OpenCode plugin/agent files and leaves all other user config alone.

type PiInstaller

type PiInstaller struct {
	// Home is the resolved Pi config directory ($PI_HOME or ~/.pi).
	// Override only in tests.
	Home string
}

PiInstaller manages the Pi activity-sidecar marker file. The TypeScript sidecar writes the same marker at runtime so `questmaster hooks status pi` can detect stale non-symlink installs.

func NewPiInstaller

func NewPiInstaller(home string) *PiInstaller

NewPiInstaller resolves $PI_HOME / $HOME.

func (*PiInstaller) Install

func (p *PiInstaller) Install() error

Install implements Installer. It writes the current sidecar marker atomically and is idempotent.

func (*PiInstaller) InstallWithOptions

func (p *PiInstaller) InstallWithOptions(opts InstallOptions) error

InstallWithOptions writes the current marker.

func (*PiInstaller) Name

func (p *PiInstaller) Name() string

Name implements Installer.

func (*PiInstaller) Status

func (p *PiInstaller) Status() Report

Status implements Installer.

func (*PiInstaller) Uninstall

func (p *PiInstaller) Uninstall() error

Uninstall implements Installer.

type Report

type Report struct {
	Agent  string
	Status Status
	Detail string
}

Report is the per-agent status row.

type Status

type Status string

Status enumerates the per-agent installation states reported by `questmaster hooks status`.

const (
	StatusCurrent      Status = "Current"
	StatusOutdated     Status = "Outdated"
	StatusUntrusted    Status = "Untrusted"
	StatusModified     Status = "Modified"
	StatusNotInstalled Status = "NotInstalled"
)

Jump to

Keyboard shortcuts

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