Documentation
¶
Index ¶
- Constants
- Variables
- func CWDFromContext(ctx context.Context) string
- func CaptureAndRoute(ctx context.Context, provider HookProvider, event *Event, bh *broker.Handle, ...) error
- func DeleteCaptureState(sessionID string) error
- func DeleteCaptureStateByKey(key string) error
- func Dispatch(ctx context.Context, provider HookProvider, event *Event, bh *broker.Handle, ...) error
- func HookTimestampFromContext(ctx context.Context) int64
- func ModelFromContext(ctx context.Context) string
- func RegisterProvider(p HookProvider)
- func SaveCaptureState(state *CaptureState) error
- type CaptureState
- type DirectHookEmitter
- type Event
- type EventType
- type HookProvider
- type SubagentDiscoverer
- type TranscriptPreparer
Constants ¶
const ManagedCommand = "semantica"
ManagedCommand is the CLI command provider hooks should invoke by default. It intentionally uses the bare executable name so hook configs survive moves between install locations like Homebrew, curl installs, and local rebuilds.
Variables ¶
var CWDKey = cwdKeyType{}
CWDKey carries the working directory from capture state into ReadFromOffset for providers whose transcripts don't embed a project path.
var CaptureTimestampKey = captureTimestampKeyType{}
CaptureTimestampKey carries the capture state's unix-ms timestamp into ReadFromOffset for turn-scoped enrichment.
var ErrNoCaptureState = errors.New("no capture state")
ErrNoCaptureState is returned when no capture state file exists for a session.
var HookEventTypeKey = hookEventTypeKeyType{}
HookEventTypeKey carries the current lifecycle event type into provider transcript preparation.
var HookTimestampKey = hookTimestampKeyType{}
HookTimestampKey carries the current hook timestamp into provider transcript preparation.
var ModelKey = modelKeyType{}
ModelKey carries the hook event's model name into ReadFromOffset.
Functions ¶
func CWDFromContext ¶
CWDFromContext extracts the working directory from the context, or "" if absent.
func CaptureAndRoute ¶
func CaptureAndRoute(ctx context.Context, provider HookProvider, event *Event, bh *broker.Handle, blobStore *blobs.Store) error
CaptureAndRoute reads a transcript delta, routes the resulting events, and advances the saved offset only after every repo write succeeds.
func DeleteCaptureState ¶
DeleteCaptureState removes a capture state file by session ID.
func DeleteCaptureStateByKey ¶
DeleteCaptureStateByKey removes a capture state file by its key.
func Dispatch ¶
func Dispatch(ctx context.Context, provider HookProvider, event *Event, bh *broker.Handle, blobStore *blobs.Store) error
Dispatch routes a normalized hook event.
func HookTimestampFromContext ¶
HookTimestampFromContext extracts the current hook timestamp in unix-ms, or 0 if absent.
func ModelFromContext ¶
ModelFromContext extracts the model name from the context, or "" if absent.
func RegisterProvider ¶
func RegisterProvider(p HookProvider)
RegisterProvider registers a hook provider by name. Called by provider packages in their init() functions.
func SaveCaptureState ¶
func SaveCaptureState(state *CaptureState) error
SaveCaptureState writes a capture state file atomically.
Types ¶
type CaptureState ¶
type CaptureState struct {
SessionID string `json:"session_id"`
StateKey string `json:"state_key,omitempty"` // Override key; defaults to SessionID.
Provider string `json:"provider"`
TranscriptRef string `json:"transcript_ref"`
TranscriptOffset int `json:"transcript_offset"`
Timestamp int64 `json:"timestamp"`
TurnID string `json:"turn_id,omitempty"`
PromptSubmittedAt int64 `json:"prompt_submitted_at,omitempty"`
CWD string `json:"cwd,omitempty"` // working directory from hook payload
}
CaptureState tracks the read position for an active transcript. Created when a turn starts, advanced on each capture, and removed after the turn finishes. Stored globally at ~/.semantica/capture/.
State file naming uses Key(): parent states are keyed by SessionID, subagent states by a derived identifier (e.g., the subagent transcript basename), so each transcript gets its own independent offset.
func LoadActiveCaptureStates ¶
func LoadActiveCaptureStates() ([]*CaptureState, error)
LoadActiveCaptureStates scans all capture state files. Used by commit-time catch-up to flush all active sessions across all repos.
func LoadCaptureState ¶
func LoadCaptureState(sessionID string) (*CaptureState, error)
LoadCaptureState reads a capture state file for the given session. Returns ErrNoCaptureState if the file does not exist.
func LoadCaptureStateByKey ¶
func LoadCaptureStateByKey(key string) (*CaptureState, error)
LoadCaptureStateByKey reads a capture state file by its key. Returns ErrNoCaptureState if the file does not exist.
func (*CaptureState) Key ¶
func (s *CaptureState) Key() string
Key returns the identifier used for the state file name. Subagent states set StateKey explicitly; parent states fall back to SessionID.
type DirectHookEmitter ¶
type DirectHookEmitter interface {
// BuildHookEvents constructs RawEvents from a hook Event's payload fields.
// Called by the dispatcher for ToolStepCompleted, SubagentPromptSubmitted,
// SubagentCompleted, and optionally PromptSubmitted. The provider stores
// blobs via bs and returns fully populated RawEvents ready for routing and
// writing.
BuildHookEvents(ctx context.Context, event *Event, bs api.BlobPutter) ([]broker.RawEvent, error)
}
DirectHookEmitter is an optional interface for providers that can emit RawEvents directly from hook payloads without waiting for transcript replay. Used by providers that expose structured hook payloads for prompt and tool events such as Write, Edit, Bash, and Agent.
type Event ¶
type Event struct {
Type EventType
SessionID string
TranscriptRef string // path to transcript file
Prompt string // user prompt (PromptSubmitted only)
Model string // LLM model name
Timestamp int64 // unix ms, from hook payload or time.Now()
ToolUseID string // for subagent events and tool steps
SubagentID string
Metadata map[string]string
// Step capture fields (ToolStepCompleted, SubagentPromptSubmitted).
TurnID string // resolved from capture state or set by dispatcher
CWD string // working directory from hook payload
ToolName string // Write, Edit, Bash, Agent, etc.
ToolInput json.RawMessage // raw tool_input from hook payload
ToolResponse json.RawMessage // raw tool_response from hook payload
}
Event is the provider-agnostic representation of an agent lifecycle event. Produced by HookProvider.ParseHookEvent from provider-specific stdin JSON.
type EventType ¶
type EventType int
EventType represents a normalized agent lifecycle event.
func HookEventTypeFromContext ¶
HookEventTypeFromContext extracts the current lifecycle event type from the context, or false if absent.
func (EventType) HookPhase ¶
HookPhase returns a short stable string for the event's lifecycle phase. Used by providers to disambiguate event IDs when the same tool_use_id appears in both a pre and post hook (e.g., PreToolUse[Agent] and PostToolUse[Agent] share a tool_use_id but are different events).
type HookProvider ¶
type HookProvider interface {
// Name returns the provider identifier (e.g., "claude-code").
Name() string
// DisplayName returns a human-friendly label (e.g., "Claude Code").
DisplayName() string
// IsAvailable reports whether the provider can be discovered on this
// machine, either via an executable or provider-specific local state.
IsAvailable() bool
// InstallHooks writes hook configuration to the provider's repo-local
// config file (e.g., <repoRoot>/.claude/settings.json). Returns the
// number of hooks installed.
InstallHooks(ctx context.Context, repoRoot string, binaryPath string) (int, error)
// UninstallHooks removes Semantica hooks from the provider's repo-local
// config file.
UninstallHooks(ctx context.Context, repoRoot string) error
// AreHooksInstalled checks if Semantica hooks are configured in the
// given repo.
AreHooksInstalled(ctx context.Context, repoRoot string) bool
// HookBinary returns the executable name or path configured in the
// provider's hook settings for the given repo.
// Returns only the binary token, not the full command line with arguments.
// Used by health checks to verify the binary is actually reachable via
// exec.LookPath.
HookBinary(ctx context.Context, repoRoot string) (string, error)
// ParseHookEvent parses stdin JSON into a normalized Event.
ParseHookEvent(ctx context.Context, hookName string, stdin io.Reader) (*Event, error)
// TranscriptOffset returns the current position in the transcript
// (line count for JSONL, message count for JSON).
// Called during PromptSubmitted to capture the offset before the agent acts.
TranscriptOffset(ctx context.Context, transcriptRef string) (int, error)
// ReadFromOffset reads the transcript starting at the given offset and
// returns parsed RawEvents. This is the enrichment step - extracting
// file paths, token usage, tool calls from the provider's format.
ReadFromOffset(ctx context.Context, transcriptRef string, offset int, bs api.BlobPutter) ([]broker.RawEvent, int, error)
}
HookProvider is implemented by each agent provider for hook-based capture.
func GetProvider ¶
func GetProvider(name string) HookProvider
GetProvider returns the registered provider for the given name, or nil.
func ListAvailableProviders ¶
func ListAvailableProviders() []HookProvider
ListAvailableProviders returns registered providers whose agent is detected on the current machine, in canonical order.
func ListProviders ¶
func ListProviders() []HookProvider
ListProviders returns all registered providers in canonical order.
type SubagentDiscoverer ¶
type SubagentDiscoverer interface {
// DiscoverSubagentTranscripts returns paths to all subagent transcript
// files associated with the given parent transcript. The parent transcript
// path is used to derive the subagents directory (provider-specific).
DiscoverSubagentTranscripts(ctx context.Context, parentTranscriptRef string) ([]string, error)
// SubagentStateKey returns a stable key for the subagent's capture state
// file, derived from the subagent transcript path. Must be unique per
// subagent and safe for use as a filename component.
SubagentStateKey(subagentTranscriptRef string) string
}
SubagentDiscoverer is an optional interface for providers that support subagent (child) transcripts stored separately from the parent transcript. When implemented, the SubagentCompleted handler scans for child transcripts and reads each one with its own capture state, ensuring subagent edits are attributed correctly.
type TranscriptPreparer ¶
type TranscriptPreparer interface {
// PrepareTranscript ensures the transcript file is complete and readable.
// Called before ReadFromOffset. Must block until the file is ready or
// a timeout is reached. Return nil on timeout so
// capture proceeds with whatever data is available.
PrepareTranscript(ctx context.Context, transcriptRef string) error
}
TranscriptPreparer is an optional interface for providers whose transcripts may not be fully flushed to disk when the hook fires. If implemented, PrepareTranscript is called before every ReadFromOffset.