Documentation
¶
Overview ¶
Critical no-block safeguards for transaction-like pages.
Why this exists: Blocking the wrong page can break real-world user actions with consequences, such as failed payments, lost checkout sessions, duplicate charges, expired 3DS challenges, or interrupted booking/reservation confirmations. Those are high-cost interruptions, so we bias toward safety and avoid classifying such flows as distracting.
How it works:
- Deterministic URL/provider signals catch high-confidence payment and booking flows (e.g. known gateway hosts and checkout/billing/confirmation paths) and force neutral.
- Suspicious context detection marks ambiguous cases so callers can apply a fail-safe neutral outcome when LLM classification is uncertain (error/low confidence).
This keeps strict protection where it matters while reducing false positives from weak keyword-only title/content matches.
Index ¶
- Constants
- func FetchMainContent(ctx context.Context, rawURL string) (string, error)
- func NewSandboxContext(opts ...sandboxContextOption) sandboxContext
- func WithAppNameContext(appName string) sandboxContextOption
- func WithBrowserURLContext(url string) sandboxContextOption
- func WithMinutesSinceLastBlockContext(minutesSinceLastBlock int) sandboxContextOption
- func WithMinutesUsedInPeriodContext(...) sandboxContextOption
- func WithMinutesUsedSinceLastBlockContext(minutesUsedSinceLastBlock int) sandboxContextOption
- func WithNowContext(now time.Time) sandboxContextOption
- func WithWindowTitleContext(title string) sandboxContextOption
- type AppClassifier
- type Application
- type ApplicationTagsSlice
- type ApplicationUsage
- func (a *ApplicationUsage) CommunicationChannel() string
- func (a *ApplicationUsage) GetDetectedProject() string
- func (a *ApplicationUsage) HasDetectedProject() bool
- func (a *ApplicationUsage) IsCommunicationUsage() bool
- func (a ApplicationUsage) Same(a1 ApplicationUsage) bool
- func (a *ApplicationUsage) String() string
- func (a *ApplicationUsage) TableName() string
- type ApplicationUsageTags
- type Classification
- type ClassificationResponse
- type ClassificationSource
- type ClassifyRequest
- type CommunicationBreakdown
- type DayInsights
- type ExecutionLogType
- type GetUsageListOptions
- type LLMAppTimeSummary
- type LLMDailySummary
- type LLMDaySummaryInput
- type LLMDeepWorkSession
- type LLMDistractionCascade
- type MetaData
- type Option
- type PauseRequets
- type ProductivityPerHourBreakdown
- type ProductivityScore
- type ProjectBreakdown
- type ProtectionPause
- type ProtectionWhitelist
- type SandboxExecutionLog
- type Service
- func (s *Service) CalculateTerminationMode(ctx context.Context, appUsage *ApplicationUsage) (TerminationDecision, error)
- func (s *Service) ClassifyCustomRules(ctx context.Context, opts ...sandboxContextOption) (*ClassificationResponse, error)
- func (s *Service) ClassifyWithLLM(ctx context.Context, appName, title string, url, bundleID, appCategory *string) (*ClassificationResponse, error)
- func (s *Service) GenerateLLMDailySummaryIfNeeded(ctx context.Context) error
- func (s *Service) GetApplicationList() ([]Application, error)
- func (s *Service) GetDayInsights(date time.Time) (DayInsights, error)
- func (s *Service) GetPauseHistory(days int) ([]ProtectionPause, error)
- func (s *Service) GetProtectionStatus() (ProtectionPause, error)
- func (s *Service) GetSandboxExecutionLogs(logType string, search string, page, pageSize int) ([]SandboxExecutionLog, error)
- func (s *Service) GetUsageAggregation(options GetUsageListOptions) ([]UsageAggregation, error)
- func (s *Service) GetUsageList(options GetUsageListOptions) ([]ApplicationUsage, error)
- func (s *Service) GetWhitelist() ([]ProtectionWhitelist, error)
- func (s *Service) IdleChanged(ctx context.Context, isIdle bool) (*ApplicationUsage, error)
- func (s *Service) OnLLMDailySummaryReady(fn func(summary LLMDailySummary))
- func (s *Service) OnProtectionPause(fn func(pause ProtectionPause))
- func (s *Service) OnProtectionResumed(fn func(pause ProtectionPause))
- func (s *Service) OnUsageUpdated(fn func(usage *ApplicationUsage))
- func (s *Service) PauseProtection(durationSeconds int, reason string) (ProtectionPause, error)
- func (s *Service) RegisterHTTPHandlers(r *chi.Mux)
- func (s *Service) RemoveWhitelist(id int64) error
- func (s *Service) ResumeProtection(reason string) (ProtectionPause, error)
- func (s *Service) TitleChanged(ctx context.Context, executablePath, windowTitle, appName, icon string, ...) (*ApplicationUsage, error)
- func (s *Service) Whitelist(appname string, url string, duration time.Duration) error
- type TerminationDecision
- type TerminationMode
- type TerminationModeSource
- type UnpauseRequest
- type UnwhitelistRequest
- type UsageAggregation
- type WhitelistRequest
Constants ¶
const ( TerminationModeNone TerminationMode = "none" TerminationModeBlock TerminationMode = "block" TerminationModeAllow TerminationMode = "allow" TerminationModeSourceApplication TerminationModeSource = "application" TerminationModeSourceCustomRules TerminationModeSource = "custom_rules" TerminationModeSourceWhitelist TerminationModeSource = "whitelist" TerminationModeSourcePaused TerminationModeSource = "paused" ClassificationSourceUserSet ClassificationSource = "user_set" ClassificationSourceObviously ClassificationSource = "obviously" ClassificationSourceCustomRules ClassificationSource = "custom_rules" ClassificationSourceCloudLLMGemini ClassificationSource = "llm_gemini" ClassificationSourceCloudLLMOpenAI ClassificationSource = "llm_openai" ClassificationSourceCloudLLMGroq ClassificationSource = "llm_grok" ClassificationSourceCloudLLMAnthropic ClassificationSource = "llm_anthropic" IdleApplicationName = "Idle" ClassificationNone Classification = "none" ClassificationProductive Classification = "productive" ClassificationDistracting Classification = "distracting" ClassificationNeutral Classification = "neutral" ClassificationSystem Classification = "system" )
Variables ¶
This section is empty.
Functions ¶
func NewSandboxContext ¶ added in v0.0.34
func NewSandboxContext(opts ...sandboxContextOption) sandboxContext
func WithAppNameContext ¶ added in v0.0.34
func WithAppNameContext(appName string) sandboxContextOption
func WithBrowserURLContext ¶ added in v0.0.34
func WithBrowserURLContext(url string) sandboxContextOption
func WithMinutesSinceLastBlockContext ¶ added in v0.0.34
func WithMinutesSinceLastBlockContext(minutesSinceLastBlock int) sandboxContextOption
func WithMinutesUsedInPeriodContext ¶ added in v0.0.34
func WithMinutesUsedSinceLastBlockContext ¶ added in v0.0.34
func WithMinutesUsedSinceLastBlockContext(minutesUsedSinceLastBlock int) sandboxContextOption
func WithNowContext ¶ added in v0.0.34
func WithWindowTitleContext ¶ added in v0.0.34
func WithWindowTitleContext(title string) sandboxContextOption
Types ¶
type AppClassifier ¶ added in v0.0.34
type Application ¶
type Application struct {
// mandatory fields
ID int64 `json:"id" gorm:"primaryKey;autoIncrement;not null"`
Name string `json:"name" gorm:"uniqueIndex:idx_name_hostname_id;not null"`
// optional fields
Icon *string `json:"icon"` // either app icon or favicon if host is present
Hostname *string `json:"hostname" gorm:"uniqueIndex:idx_name_hostname_id"`
Domain *string `json:"domain"`
ExecutablePath string `json:"executable_path"`
// darwin only
BundleID *string `json:"bundle_id"`
AppCategory *string `json:"app_category"` // LSApplicationCategoryType, e.g. "public.app-category.developer-tools"
}
Application represents a unique application that has been used by the user Application is unique by name and hostname that is
- if the application is not a browser it is unique by name
- if the application is a browser it is unique by name and domain eg. Chrome + google.com != Chrome + youtube.com, each of them will have its own application
func NewIdleApplication ¶ added in v0.0.34
func NewIdleApplication() Application
func (Application) NewUsage ¶ added in v0.0.34
func (a Application) NewUsage(windowTitle string, browserURL *string) ApplicationUsage
func (Application) TableName ¶ added in v0.0.25
func (a Application) TableName() string
type ApplicationTagsSlice ¶ added in v0.0.25
type ApplicationTagsSlice []ApplicationUsageTags
func (ApplicationTagsSlice) Tags ¶ added in v0.0.25
func (a ApplicationTagsSlice) Tags() []string
type ApplicationUsage ¶
type ApplicationUsage struct {
// mandatory fields
ID int64 `json:"id" gorm:"primaryKey;autoIncrement;not null"`
WindowTitle string `json:"window_title" gorm:"not null"`
StartedAt int64 `json:"started_at" gorm:"not null"`
Classification Classification `json:"classification" gorm:"index:idx_classification"`
TerminationMode TerminationMode `json:"termination_mode" gorm:"not null"`
// optional fields
BrowserURL *string `json:"browser_url" gorm:"type:text"`
EndedAt *int64 `json:"ended_at"`
DurationSeconds *int `json:"duration_seconds"`
ClassificationError *string `gorm:"index:idx_classification_error" json:"classification_error"`
ClassificationConfidence *float32 `json:"classification_confidence"`
ClassificationReasoning *string `json:"classification_reasoning"`
ClassificationSource *ClassificationSource `json:"classification_source"`
DetectedProject *string `gorm:"index:idx_detected_project" json:"detected_project"`
DetectedCommunicationChannel *string `gorm:"index:idx_detected_communication_channel" json:"detected_communication_channel"`
TerminationReasoning *string `json:"termination_reasoning"`
TerminationSource *TerminationModeSource `json:"termination_mode_source"`
TerminationError *string `gorm:"index:idx_termination_mode_error" json:"termination_mode_error"`
SandboxContext *string `json:"sandbox_context" gorm:"type:text;nullable"`
SandboxResponse *string `json:"sandbox_response" gorm:"type:text;nullable"`
SandboxLogs *string `json:"sandbox_logs" gorm:"type:text;nullable"`
// relations
Tags []ApplicationUsageTags `gorm:"foreignKey:UsageID" json:"tags"`
ApplicationID int64 `json:"application_id"`
Application Application `gorm:"foreignKey:ApplicationID" json:"application"`
}
func (*ApplicationUsage) CommunicationChannel ¶ added in v0.0.33
func (a *ApplicationUsage) CommunicationChannel() string
func (*ApplicationUsage) GetDetectedProject ¶ added in v0.0.33
func (a *ApplicationUsage) GetDetectedProject() string
func (*ApplicationUsage) HasDetectedProject ¶ added in v0.0.33
func (a *ApplicationUsage) HasDetectedProject() bool
func (*ApplicationUsage) IsCommunicationUsage ¶ added in v0.0.33
func (a *ApplicationUsage) IsCommunicationUsage() bool
func (ApplicationUsage) Same ¶
func (a ApplicationUsage) Same(a1 ApplicationUsage) bool
Same returns true if the application usage is the same as the given application usage
func (*ApplicationUsage) String ¶ added in v0.0.34
func (a *ApplicationUsage) String() string
func (*ApplicationUsage) TableName ¶
func (a *ApplicationUsage) TableName() string
type ApplicationUsageTags ¶
type ApplicationUsageTags struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
Tag string `json:"tag"`
UsageID int64 `json:"usage_id" gorm:"index:idx_usage_id"`
}
func (*ApplicationUsageTags) TableName ¶ added in v0.0.34
func (a *ApplicationUsageTags) TableName() string
type Classification ¶
type Classification string
func (Classification) IsProductiveOrDistracting ¶ added in v0.0.33
func (c Classification) IsProductiveOrDistracting() bool
type ClassificationResponse ¶
type ClassificationResponse struct {
Classification Classification `json:"classification"`
ClassificationSource ClassificationSource `json:"classification_source"`
Reasoning string `json:"reasoning"`
ConfidenceScore float32 `json:"confidence_score"`
// DetectedProject is inferred by the LLM from the window title or channel name.
// For coding apps (VS Code, Xcode, etc.), it extracts the workspace/project name from the title format.
// For communication apps (Slack), it extracts the project/team context if strongly implied by the channel name.
DetectedProject string `json:"detected_project"`
// DetectedCommunicationChannel is inferred by the LLM from the window title for communication apps.
// E.g., for Slack it extracts "engineering" from "Slack | #engineering | Acme Corp".
// This is only populated when the "communication" tag is assigned.
DetectedCommunicationChannel string `json:"detected_communication_channel"`
Tags []string `json:"tags"`
SandboxContext string `json:"sandbox_context"`
SandboxResponse *string `json:"sandbox_response"`
SandboxLogs string `json:"sandbox_logs"`
}
type ClassificationSource ¶
type ClassificationSource string
type ClassifyRequest ¶
type ClassifyRequest struct {
AppName string `json:"app_name"`
ExecutablePath string `json:"executable_path"`
Hostname string `json:"hostname"`
URL string `json:"url"`
Classification Classification `json:"classification"`
}
type CommunicationBreakdown ¶ added in v0.0.31
type DayInsights ¶
type DayInsights struct {
ProductivityScore ProductivityScore `json:"productivity_score"`
ProductivityPerHourBreakdown ProductivityPerHourBreakdown `json:"productivity_per_hour_breakdown"`
LLMDailySummary *LLMDailySummary `json:"llm_daily_summary"`
TopDistractions map[string]int `json:"top_distractions"`
TopBlocked map[string]int `json:"top_blocked"`
ProjectBreakdown map[string]int `json:"project_breakdown"`
CommunicationBreakdown map[string]CommunicationBreakdown `json:"communication_breakdown"`
}
type ExecutionLogType ¶ added in v0.0.21
type ExecutionLogType string
const ( ExecutionLogTypeClassification ExecutionLogType = "classification" ExecutionLogTypeTerminationMode ExecutionLogType = "termination_mode" )
type GetUsageListOptions ¶
type LLMAppTimeSummary ¶ added in v0.0.31
type LLMDailySummary ¶ added in v0.0.31
type LLMDailySummary struct {
ID int64 `json:"id" gorm:"primaryKey;autoIncrement"`
Date string `json:"date" gorm:"uniqueIndex;not null"`
Headline string `json:"headline"`
Narrative string `json:"narrative"`
KeyPattern string `json:"key_pattern"`
Wins string `json:"wins"` // JSON array of strings
Suggestion string `json:"suggestion"`
DayVibe string `json:"day_vibe"`
ContextSwitchCount int `json:"context_switch_count"`
LongestFocusMinutes int `json:"longest_focus_minutes"`
DeepWorkMinutes int `json:"deep_work_minutes"`
BlockedAttemptCount int `json:"blocked_attempt_count"`
CreatedAt int64 `json:"created_at"`
}
LLMDailySummary is the persisted daily summary generated by the LLM.
func (LLMDailySummary) TableName ¶ added in v0.0.31
func (LLMDailySummary) TableName() string
type LLMDaySummaryInput ¶ added in v0.0.31
type LLMDaySummaryInput struct {
Date string `json:"date"`
TotalProductiveMinutes int `json:"total_productive_minutes"`
TotalDistractiveMinutes int `json:"total_distractive_minutes"`
FocusScore int `json:"focus_score"`
ContextSwitchCount int `json:"context_switch_count"`
LongestFocusStretchMin int `json:"longest_focus_stretch_min"`
DeepWorkSessions []LLMDeepWorkSession `json:"deep_work_sessions"`
DeepWorkTotalMinutes int `json:"deep_work_total_minutes"`
DistractionCascades []LLMDistractionCascade `json:"distraction_cascades"`
TopDistractions []LLMAppTimeSummary `json:"top_distractions"`
TopProductiveApps []LLMAppTimeSummary `json:"top_productive_apps"`
MostProductiveHours string `json:"most_productive_hours"`
MostDistractiveHours string `json:"most_distractive_hours"`
BlockedAttemptCount int `json:"blocked_attempt_count"`
ProtectionPauseCount int `json:"protection_pause_count"`
AvgFocusScoreLast7Days int `json:"avg_focus_score_last_7_days"`
FocusScoreTrend string `json:"focus_score_trend"`
}
LLMDaySummaryInput is the pre-computed data that gets serialized and sent to the LLM. It is never stored -- only used as an intermediate representation.
type LLMDeepWorkSession ¶ added in v0.0.31
type LLMDistractionCascade ¶ added in v0.0.31
type PauseRequets ¶
type ProductivityPerHourBreakdown ¶
type ProductivityPerHourBreakdown map[int]ProductivityScore
type ProductivityScore ¶
type ProjectBreakdown ¶ added in v0.0.31
type ProtectionPause ¶
type ProtectionPause struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
RequestedDurationSeconds int `json:"requested_duration_seconds"`
ActualDurationSeconds int `json:"actual_duration_seconds"`
ResumedAt int64 `json:"resumed_at"`
ResumedReason string `json:"resumed_reason"`
CreatedAt int64 `json:"created_at"`
Reason string `json:"reason"`
}
func (*ProtectionPause) TableName ¶
func (p *ProtectionPause) TableName() string
type ProtectionWhitelist ¶
type ProtectionWhitelist struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
// ExpiresAt should be pre-calculated and set to the time when the whitelist expires
ExpiresAt int64 `json:"expires_at"`
AppName string `gorm:"uniqueIndex:idx_allow_usage_identity" json:"appname"`
Hostname *string `gorm:"uniqueIndex:idx_allow_usage_identity" json:"hostname"`
}
func (*ProtectionWhitelist) TableName ¶
func (p *ProtectionWhitelist) TableName() string
type SandboxExecutionLog ¶
type SandboxExecutionLog struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
Context string `json:"context" gorm:"type:text;nullable"`
Response *string `json:"response" gorm:"type:text;nullable"`
Logs string `json:"logs" gorm:"type:text;nullable"`
CreatedAt int64 `json:"created_at" gorm:"index:idx_created_at"`
FinishedAt *int64 `json:"finished_at" gorm:"index:idx_finished_at;nullable"`
Error *string `json:"error" gorm:"type:text;nullable"`
Type string `json:"type" gorm:"index:idx_type"`
}
func (*SandboxExecutionLog) TableName ¶ added in v0.0.34
func (s *SandboxExecutionLog) TableName() string
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func (*Service) CalculateTerminationMode ¶
func (s *Service) CalculateTerminationMode(ctx context.Context, appUsage *ApplicationUsage) (TerminationDecision, error)
CalculateTerminationMode determines whether an application or website should be blocked, allowed, or paused based on classification, custom rules, protection status, and whitelist entries.
This function evaluates multiple factors in order of priority: 1. Custom rules (if configured) - highest priority 2. Classification - non-distracting usage is always allowed 3. Protection pause status - if protection is paused, usage is allowed 4. Whitelist entries - temporarily whitelisted bundle ID/hostname combinations are allowed 5. Default blocking - distracting usage is blocked when protection is active
Parameters:
- bundleID: The application bundle identifier (e.g., "com.example.app")
- hostname: The website hostname (e.g., "example.com") - empty string for non-browser apps
- domain: The domain name extracted from the URL
- url: The full URL being accessed
- classification: The classification result indicating whether the usage is distracting
- terminationMode: The requested termination mode (may be overridden by custom rules)
Returns:
- TerminationDecision: A decision containing the mode (Allow/Block/Paused), reasoning, and source
- error: Database error if protection status or whitelist lookup fails
func (*Service) ClassifyCustomRules ¶
func (s *Service) ClassifyCustomRules(ctx context.Context, opts ...sandboxContextOption) (*ClassificationResponse, error)
func (*Service) ClassifyWithLLM ¶
func (*Service) GenerateLLMDailySummaryIfNeeded ¶ added in v0.0.31
func (*Service) GetApplicationList ¶ added in v0.0.34
func (s *Service) GetApplicationList() ([]Application, error)
func (*Service) GetDayInsights ¶
func (s *Service) GetDayInsights(date time.Time) (DayInsights, error)
func (*Service) GetPauseHistory ¶
func (s *Service) GetPauseHistory(days int) ([]ProtectionPause, error)
GetPauseHistory retrieves the history of protection pauses within the specified number of days.
Parameters:
- days: The number of days to look back (e.g., 7 for one week)
Returns:
- []ProtectionPause: A slice of pause records ordered by creation time (newest first)
- error: Database error if the query fails
func (*Service) GetProtectionStatus ¶
func (s *Service) GetProtectionStatus() (ProtectionPause, error)
GetProtectionStatus retrieves the current protection pause status.
It queries for an active ProtectionPause record where ResumedAt is greater than the current time (indicating the pause is still active and hasn't been resumed yet). When a pause is created, ResumedAt is set to a future timestamp representing when the pause should automatically expire. When manually resumed, ResumedAt is updated to the current time, making it no longer match this query.
Returns:
- ProtectionPause: The active pause record if protection is currently paused, or an empty ProtectionPause (ID == 0) if protection is active (not paused)
- error: Database error if the query fails
func (*Service) GetSandboxExecutionLogs ¶ added in v0.0.21
func (s *Service) GetSandboxExecutionLogs(logType string, search string, page, pageSize int) ([]SandboxExecutionLog, error)
GetSandboxExecutionLogs retrieves paginated sandbox execution logs from the database. It supports fuzzy search on context and response fields, and filtering by log type. Only returns logs from the last 7 days.
func (*Service) GetUsageAggregation ¶ added in v0.0.24
func (s *Service) GetUsageAggregation(options GetUsageListOptions) ([]UsageAggregation, error)
func (*Service) GetUsageList ¶
func (s *Service) GetUsageList(options GetUsageListOptions) ([]ApplicationUsage, error)
GetUsageList returns a list of application usages for the given date and pagination options
Parameters:
- options: GetUsageListOptions
- Date: The date to get usages for - useful for detailed analysis of a specific day usage
- Page: The page number to get
- PageSize: The number of usages per page
Returns:
- []ApplicationUsage: The list of application usages
func (*Service) GetWhitelist ¶
func (s *Service) GetWhitelist() ([]ProtectionWhitelist, error)
GetWhitelist returns all active whitelist entries that haven't expired.
Returns:
- []ProtectionWhitelist: A slice of active whitelist entries
- error: Database error if the query fails
func (*Service) IdleChanged ¶
IdleChanged is called when the idle state of the user changes (e.g. user starts or stops using the computer) When idle changes one of the following can happen:
- if user has been idle and idle triggers again, keep the current idle usage open to ensure idempotency
- if user has not been idle and idle triggers, close the current application usage and open a new idle usage
- if user has been idle and idle stops, no direct usage change is performed here; the next TitleChanged event closes idle
func (*Service) OnLLMDailySummaryReady ¶ added in v0.0.34
func (s *Service) OnLLMDailySummaryReady(fn func(summary LLMDailySummary))
OnLLMDailySummaryReady subscribes a callback to the daily summary ready event.
func (*Service) OnProtectionPause ¶ added in v0.0.34
func (s *Service) OnProtectionPause(fn func(pause ProtectionPause))
OnProtectionPause subscribes a callback to the protection paused event.
func (*Service) OnProtectionResumed ¶ added in v0.0.34
func (s *Service) OnProtectionResumed(fn func(pause ProtectionPause))
OnProtectionResumed subscribes a callback to the protection resumed event.
func (*Service) OnUsageUpdated ¶ added in v0.0.34
func (s *Service) OnUsageUpdated(fn func(usage *ApplicationUsage))
OnUsageUpdated subscribes a callback to the usage updated event.
func (*Service) PauseProtection ¶
func (s *Service) PauseProtection(durationSeconds int, reason string) (ProtectionPause, error)
PauseProtection temporarily disables focus protection for the specified duration.
The function starts a background goroutine that automatically resumes protection after the duration expires. The pause state is persisted to the database, allowing the application to recover pause state across restarts.
Parameters:
- duration: The duration to pause protection (must be > 0)
Returns:
- error: Returns an error if protection is already paused
Side effects:
- Creates a ProtectionPause record in the database
- Emits a state update via the state channel
- Spawns a goroutine that calls ResumeProtection after the duration
func (*Service) RegisterHTTPHandlers ¶
func (*Service) RemoveWhitelist ¶
RemoveWhitelist removes a whitelist entry by ID.
Parameters:
- id: The ID of the whitelist entry to remove
Returns:
- error: Database error if the deletion fails
func (*Service) ResumeProtection ¶
func (s *Service) ResumeProtection(reason string) (ProtectionPause, error)
ResumeProtection re-enables focus protection and records the reason for resumption.
This function is called either automatically when a pause duration expires, or manually by the user to end a pause early. The reason is persisted to the database for auditing and analytics purposes.
Parameters:
- reason: A human-readable explanation for why protection was resumed (e.g., "protection paused for 5m0s expired" or "user manually resumed")
Returns:
- error: Returns an error if protection is not currently paused
Side effects:
- Updates the ProtectionPause record in the database with ResumedAt timestamp
- Clears the pause state and emits a state update via the state channel
func (*Service) TitleChanged ¶
func (s *Service) TitleChanged(ctx context.Context, executablePath, windowTitle, appName, icon string, bundleID, browserURL, appCategory *string) (*ApplicationUsage, error)
TitleChanged is called when the title of the current application changes, whether it's a new application or the same application title has changed
func (*Service) Whitelist ¶
Whitelist temporarily allows a specific blocked usage (by bundle ID and hostname) for the specified duration.
This function creates a ProtectionWhitelist entry that allows the specified application or website to bypass focus protection for a limited time. This enables users to temporarily access blocked content without pausing all protection. The whitelist entry is persisted to the database and can be checked during termination decision evaluation.
Parameters:
- bundleID: The application bundle identifier (e.g., "com.example.app")
- hostname: The website hostname (e.g., "example.com") - empty string for non-browser apps
- duration: The duration to allow the usage (defaults to 1 hour if 0)
Returns:
- error: Database error if the whitelist entry creation fails
Side effects:
- Creates a ProtectionWhitelist record in the database with expiration timestamp
type TerminationDecision ¶
type TerminationDecision struct {
Mode TerminationMode
Reasoning string
Source TerminationModeSource
}
type TerminationMode ¶
type TerminationMode string
type TerminationModeSource ¶
type TerminationModeSource string
type UnpauseRequest ¶
type UnpauseRequest struct {
Reason string `json:"reason"`
}
type UnwhitelistRequest ¶ added in v0.0.24
type UnwhitelistRequest struct {
ID int64 `json:"id"`
}
type UsageAggregation ¶ added in v0.0.24
type UsageAggregation struct {
Application Application `json:"application"`
TotalDuration int `json:"total_duration"` // in seconds
UsageCount int `json:"usage_count"`
}
type WhitelistRequest ¶ added in v0.0.24
Source Files
¶
- classifier_critical_pages.go
- classifier_custom_rules.go
- classifier_llm.go
- classifier_llm_apps.go
- classifier_llm_apps_prompt.go
- classifier_llm_custom.go
- classifier_llm_prompt_assets.go
- classifier_llm_website.go
- classifier_llm_website_prompt.go
- classifier_obviously.go
- http_handler.go
- insights_basic.go
- insights_daily_summary.go
- insights_report.go
- insights_summary.go
- protection.go
- sandbox.go
- sandbox_context.go
- sandbox_logs.go
- service.go
- service_events.go
- service_option.go
- service_usage.go
- types_daily_summary.go
- types_db.go
- types_insights.go
- types_usage.go
- utils.go