Documentation
¶
Index ¶
- Constants
- Variables
- func CWDFromContext(ctx context.Context) string
- func CaptureAndRoute(ctx context.Context, provider HookProvider, event *Event, bh *broker.Handle, ...) error
- func CaptureDirWritable() 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 ExtractBinary(command string) string
- func GuardedCommand(bin, args string) string
- func HookTimestampFromContext(ctx context.Context) int64
- func MarshalCompactJSON(v any) ([]byte, error)
- func MarshalSettingsJSON(v any) ([]byte, error)
- func ModelFromContext(ctx context.Context) string
- func RegisterProvider(p HookProvider)
- func SaveCaptureState(state *CaptureState) error
- type CaptureState
- type DirectHookEmitter
- type DiscoveryContext
- 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 CaptureDirWritable ¶ added in v0.3.6
func CaptureDirWritable() error
CaptureDirWritable probes whether the global capture directory is writable.
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 ExtractBinary ¶ added in v0.3.3
ExtractBinary returns the binary path from a hook command string. Handles both guarded ("if command -v X ...; then X capture ...; fi") and unguarded ("X capture ...") formats.
func GuardedCommand ¶ added in v0.3.3
GuardedCommand wraps a capture command with a shell guard that silently no-ops when the binary is not on PATH. Ensures the hook never blocks the agent and never produces errors for teammates who don't have Semantica.
func HookTimestampFromContext ¶
HookTimestampFromContext extracts the current hook timestamp in unix-ms, or 0 if absent.
func MarshalCompactJSON ¶ added in v0.3.8
MarshalCompactJSON is the compact counterpart for json.RawMessage fragments embedded inside settings documents.
func MarshalSettingsJSON ¶ added in v0.3.8
MarshalSettingsJSON serializes hook settings as indented JSON without HTML escaping, keeping shell commands readable.
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 current offset for an active transcript.
func LoadActiveCaptureStates ¶
func LoadActiveCaptureStates() ([]*CaptureState, error)
LoadActiveCaptureStates scans all capture state files.
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.
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 DiscoveryContext ¶ added in v0.3.8
type DiscoveryContext struct {
// Cwd is the parent session's working directory.
Cwd string
// PromptTime is the parent's PromptSubmitted timestamp in unix-ms.
PromptTime int64
// StopTime is the upper bound of the parent's active window in unix-ms.
StopTime int64
// ParentSessionID is the parent's hook session id.
ParentSessionID string
// ParentAgentName is the parent's agent name when the provider exposes it.
ParentAgentName string
}
DiscoveryContext carries lifecycle-known facts about the parent turn for providers that store child transcripts in a directory shared with unrelated sessions and need extra signals to disambiguate. Fields may be empty; implementations must tolerate that rather than fail outright.
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.
const ( PromptSubmitted EventType = iota AgentCompleted SessionOpened SessionClosed ContextCompacted SubagentSpawned SubagentCompleted ToolStepCompleted // state-changing PostToolUse (Write, Edit, Bash) SubagentPromptSubmitted // PreToolUse[Agent] prompt event IncrementalCapture // mid-turn trigger to scan transcript from saved offset )
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 config file
// (e.g., <repoRoot>/.claude/settings.local.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. Implementations
// consume only the DiscoveryContext fields they need.
DiscoverSubagentTranscripts(ctx context.Context, parentTranscriptRef string, dctx DiscoveryContext) ([]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.
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.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package builder provides shared scaffolding for the per-provider direct-emit hook handlers under internal/hooks/<provider>.
|
Package builder provides shared scaffolding for the per-provider direct-emit hook handlers under internal/hooks/<provider>. |
|
Package testutil provides the shared golden-file harness for the direct-emit hook providers under internal/hooks/<provider>.
|
Package testutil provides the shared golden-file harness for the direct-emit hook providers under internal/hooks/<provider>. |