hooksession

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package hooksession owns the running session's resolved lifecycle-hook state: discovery, arming, and the /hooks listing text.

It is a leaf package deliberately: it imports only internal/config and internal/hooks, never internal/cli, internal/clichat, internal/agent, internal/coordinator, or internal/hub. That is what lets internal/uiadapter (which may not import any of those) reach the same session state and listing text the old CLI surface uses, without a seam indirection.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Configured

func Configured() bool

Configured reports whether any hook was discovered at all.

func Install

func Install(workspaceRoot string, staleBypass, quiet bool) (release func(), notices []string, err error)

Install resolves this session's lifecycle hooks and publishes the result for /hooks and the dispatcher wiring. The returned function releases the handle at session end.

Notices (load warnings, the armed-hook summary, and the project-hook disclosure) are returned rather than printed, so this package stays a leaf: printing is the caller's job (internal/cli's wrapper calls cliagents.WarnHookLoad with them, matching the pre-migration behavior).

quiet (--quiet) suppresses the armed notice and the project-hook disclosure: the operator explicitly asked for quieter startup, and /hooks still lists every armed hook on demand. Genuine load warnings always print.

func RunStopForTurn

func RunStopForTurn(ctx context.Context, sessionID, turnID string) string

RunStopForTurn fires Stop hooks for a completed ROOT turn and returns their output as an attributed continuation prompt.

Stop is pure observation: it has no denial channel at all, so a Stop hook can log a turn's cost and can never affect whether the turn ended.

This is internal/chat's single call site (see stop_hook.go there), reached from every surface (-p, --plain, line mode, TUI) because all four funnel through chat.Session.sendUserWithTurn, and fired once per root turn - a turn that began (sendPlain/sendAgent past beginPlainTurn/beginAgentTurn) fires Stop on every outcome (success, error, or a canceled ctx); a turn that never began (session switching or loading) fires nothing. PreToolUse and PostToolUse are unaffected: they run through the dispatcher's Policy, not through this seam.

workspaceRoot is not a parameter: it is the same directory Install resolved this session's hook argv[0] paths against (Session.workspaceRoot), so a caller that already knows its sessionID/turnID does not need to also thread the workspace root through every turn-completion path.

The context is the turn's own, deliberately not a detached one. A canceled turn therefore does not run its Stop hook, and the run is RECORDED rather than skipped silently - detaching would make Ctrl-C wait out the hook's timeout before the cancelled footer appeared.

func SetForTest

func SetForTest(s *Session) (restore func())

SetForTest installs s as the current session and returns a restore func. Exported for cross-package tests (internal/cli, internal/clichat) that need to exercise a specific hook session without going through Install.

func SlashOutput

func SlashOutput(fields []string) string

SlashOutput is the surface-independent body of /hooks.

`/hooks trust <n>` is answered rather than rejected as an unknown argument. It was a real subcommand, it will be in muscle memory and in notes, and "unknown argument" would read as a bug in the listing rather than as a removed concept.

Types

type Session

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

Session is the running session's resolved lifecycle-hook state.

func Current

func Current() *Session

Current returns the running session's hook state, or nil if none is installed. Every method on *Session is nil-safe, so callers may use the result directly without a nil check.

func Load

func Load(workspaceRoot string) (*Session, error)

Load discovers lifecycle hooks from both surfaces.

The user config at its fixed path comes first, then this workspace's own .mivia/mivia.toml. They ADD: a project's formatter and a user's global gate are two hooks, not competing answers, and ordering the user's first means a PreToolUse gate they wrote answers before a repository's does.

A project hook can therefore run code the operator did not write. What stands in for a confirmation is disclosure that cannot be missed - the startup notice, the [project] marker on every listed hook, and a transcript row per execution.

func (*Session) ArmedNotice

func (s *Session) ArmedNotice() []string

ArmedNotice names every hook that will run this session.

It replaces the confirmation prompt, and it is not a lesser thing standing in for one: a prompt asks a question whose answer was already given by editing the config, while this states a fact the operator can act on. A session that executes programs on every tool call and says nothing about it is the actual hazard.

func (*Session) List

func (s *Session) List() string

List is the /hooks listing.

func (*Session) NoteRunWarnings

func (s *Session) NoteRunWarnings(warnings []string)

NoteRunWarnings records bounded diagnostics from executed hooks.

func (*Session) RunnableGroups

func (s *Session) RunnableGroups() []hooks.Group

RunnableGroups returns the hook groups that may execute in this session.

Jump to

Keyboard shortcuts

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