Documentation
¶
Index ¶
- Constants
- Variables
- func DevicePanelEnabled(distinctID string, timeout time.Duration) bool
- func EnsureInstallID(home string) (id string, stitched bool)
- func NotesEnabled(distinctID string, timeout time.Duration) bool
- func ReadInstallID(home string) string
- func SheetProfilesFromIndexer(path string) ([]tool.SheetProfile, tool.SheetRowSource, error)
- type Options
- type PostHogClient
- type Server
- func (s *Server) Guidance(id session.SessionID, content string, cancelTool bool) error
- func (s *Server) HostSession(id session.SessionID, dir, prompt, agentName string, ...) (stop func(), existed bool, err error)
- func (s *Server) Port() int
- func (s *Server) ReplyPermission(id session.SessionID, permID, response string) bool
- func (s *Server) Serve(ctx context.Context) error
- func (s *Server) SessionPort() int
- func (s *Server) SessionRow(id session.SessionID) (*session.Session, error)
- func (s *Server) Stop()
- func (s *Server) SubscribeEvents() (<-chan bus.Event, func())
- type Theme
Constants ¶
const (
NotesFlagCLITimeout = 1500 * time.Millisecond
)
featureFlagHTTPTimeout bounds the background refresher's /decide request, and NotesFlagCLITimeout the CLI's one startup lookup (exported because the CLI packages are its callers). A one-shot CLI run must not stall on a slow PostHog, so its budget is short; the server retries on the next tick anyway.
const PostHogAPIHost = "https://app.posthog.com"
PostHogAPIHost is the PostHog instance events and flag lookups go to.
Variables ¶
var PostHogAPIKey = "phc_CGzEmfPURHyNWrG49yNJA7wY5io8URFu3sazRYTAXw6Z"
PostHogAPIKey is the PostHog project key, baked into the binary — users have no control over analytics configuration. It is a variable only so a test binary can blank it (TestMain here and in worker): with no key, Serve builds no capture client and starts no feature-flag refresher, so a test run sends nothing to PostHog. Nothing in the shipped binary assigns it.
Functions ¶
func DevicePanelEnabled ¶ added in v0.44.1
DevicePanelEnabled asks PostHog whether the device panel is on for this install. Same contract as NotesEnabled: only the CLI and the refresher call it, and request paths read the server's atomic flag instead (see devicePanelUnavailable).
func EnsureInstallID ¶ added in v0.44.0
EnsureInstallID returns the machine's PostHog distinct id, minting and saving a local one when the install script recorded none. stitched reports whether the id came from an installer (the website wrote it), which is what decides whether the one-time ogcode_installed event may fire — a locally minted id marks a machine with no download to join, so it must not report an install.
A minted id is persisted best-effort to ~/.ogcode/install-id so the browser's anonymous identity stays stable across restarts; if it cannot be written, the id is still returned and used for this run.
The web UI adopts whatever id /api/config reports (web/src/lib/posthog.ts), so on an install that had no recorded id — which used to leave the browser on a random id of its own in localStorage — the first load after upgrading moves the browser onto the minted id. That browser's analytics continue under a new PostHog person from then on; the switch happens once and the two persons are not merged.
func NotesEnabled ¶ added in v0.44.0
NotesEnabled asks PostHog whether the notes feature is on for this install. It is called from exactly two places — the server's background refresher and the CLI's one startup lookup — because it may block on the network for up to the timeout it is given. Request paths never call it: they read the server's atomic flag (see notesUnavailable), which the refresher keeps current.
func ReadInstallID ¶ added in v0.44.0
ReadInstallID returns the PostHog distinct id the install script recorded when the user copied the install command from the website, or "" when there is none. A missing file, an empty file, or a malformed id all read as "" — the id is only ever used to stitch the download and the first run together, so a bad one is simply ignored rather than reported.
func SheetProfilesFromIndexer ¶ added in v0.55.0
func SheetProfilesFromIndexer(path string) ([]tool.SheetProfile, tool.SheetRowSource, error)
SheetProfilesFromIndexer adapts the indexer's sheet profiler to the query_sheet loader seam. internal/tool cannot import internal/indexer (the cycle tool → indexer → agent → tool), so this package — the only place that sees both — converts the profiles across the boundary and hands back the row source the tool streams its table rows from (internal/sheet.StreamRows, which normalizes cells identically). The cli wires the same function.
Types ¶
type Options ¶ added in v0.36.0
type Options struct {
// NoBrowser suppresses opening the operator's browser on start. The worker
// spawns one server per worktree; none of them should open a tab.
NoBrowser bool
// Loopback binds the listener to 127.0.0.1 instead of all interfaces. The
// worker's tunnel is the only remote path to a hosted server, so a hosted
// server must not also be reachable on the machine's LAN address.
Loopback bool
// OnListen, when set, is called once with the ACTUAL bound port right after
// the listener is established — which can differ from the requested port when
// that one was busy and the bind loop walked past it. The CLI uses it to
// record a project's port; leave nil to skip (worker-spawned servers do).
OnListen func(port int)
// OnInterrupt, when set, is called when a SIGINT or SIGTERM starts the
// shutdown. The CLI uses it to tell the terminal what is happening; leave nil
// to stay quiet (worker-spawned servers do).
OnInterrupt func()
}
Options tunes a server's runtime behavior without changing what it serves. The zero value reproduces the interactive `ogcode serve` behavior.
type PostHogClient ¶ added in v0.14.0
type PostHogClient struct {
// contains filtered or unexported fields
}
PostHogClient captures server-side analytics events to a PostHog project. Events are sent via the /capture REST endpoint — no SDK dependency required. All calls are fire-and-forget with a bounded worker goroutine so they never block request handlers.
func NewPostHogClient ¶ added in v0.14.0
func NewPostHogClient(apiKey, host string) *PostHogClient
NewPostHogClient returns an active client that starts a background worker. Returns nil if apiKey is empty.
func (*PostHogClient) Capture ¶ added in v0.14.0
func (c *PostHogClient) Capture(event, distinctID string, props map[string]any)
Capture enqueues an event. Properties are merged with the default server-side properties (os, arch, version). The call is non-blocking — if the queue is full the event is dropped silently.
func (*PostHogClient) Stop ¶ added in v0.14.0
func (c *PostHogClient) Stop()
Stop drains the queue and shuts down the worker, waiting at most posthogStopTimeout; events still unsent then are dropped with the process.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func NewWithOptions ¶ added in v0.36.0
func (*Server) Guidance ¶ added in v0.36.0
Guidance injects mid-loop guidance into a running loop: the text is queued on the loop's control and, when cancelTool is set, the in-flight LLM stream and tool execution are cancelled so the loop advances to the next iteration and drains the queue. PushGuidance runs before CancelStream/CancelTool — ordering matters, see handleGuidance.
It returns an error when no loop is running for the session.
func (*Server) HostSession ¶ added in v0.36.0
func (s *Server) HostSession(id session.SessionID, dir, prompt, agentName string, viewportWidth, viewportHeight int) (stop func(), existed bool, err error)
HostSession hosts an agent loop for a session the master minted, writing the session, message and part rows this server's store needs to run it.
It is the in-process equivalent of what a worker used to do by hand (createSessionRows + RunLoop under LoopControl + permission gating) and of what the UI does over HTTP (create session + prompt). One path, not three: the loop it starts is the same startSessionLoop the prompt and resume handlers use, so hosted sessions are gated, cancellable and guided exactly like sessions driven from a browser.
The returned stop func cancels the loop (abort semantics — it does not sweep orphaned assistant messages or tool parts; the old worker cancel did not either). existed reports whether the session row was already present, which makes re-delivery of the same StartAgent command idempotent.
func (*Server) Port ¶ added in v0.36.0
Port reports the port the server actually bound. Meaningful only after Serve has bound the listener (the caller's Serve goroutine is running); callers that passed port 0 read the kernel-assigned value here to dial the tunnel.
func (*Server) ReplyPermission ¶ added in v0.36.0
ReplyPermission delivers a permission reply to the waiting agent loop. It reports false when the request is unknown (already answered, cancelled, or expired).
func (*Server) Serve ¶ added in v0.36.0
Serve runs the HTTP server until ctx is cancelled, a SIGINT/SIGTERM arrives, or Stop is called — then shuts down gracefully (in-flight requests drained within the 10s shutdown timeout, MCP torn down, DBs closed) and returns. The signal path keeps standalone `ogcode serve` behavior unchanged; a ctx-driven caller (the worker hosting one server per worktree) cancels its ctx per worktree and never has signals racing across N servers. Serve must be called once per Server.
func (*Server) SessionPort ¶ added in v0.36.0
SessionPort returns the loopback port the server answers on, or 0 before the listener has bound.
func (*Server) SessionRow ¶ added in v0.36.0
SessionRow returns the session row from this server's own store, or nil when absent. It exists so the worker (and tests) can verify a hosted session landed in the worktree server's DB without reaching into unexported fields.
func (*Server) Stop ¶ added in v0.36.0
func (s *Server) Stop()
Stop asks a Serve loop to begin graceful shutdown; Serve then returns once shutdown completes. Safe to call from another goroutine; a no-op when Serve has not started (or has already finished).
func (*Server) SubscribeEvents ¶ added in v0.36.0
SubscribeEvents exposes the server's event bus to the worker, which relays hosted-session events to the master. The returned func unsubscribes.
type Theme ¶
type Theme struct {
Directory string `json:"directory"`
PrimaryColor string `json:"primaryColor"` // hex input from user, e.g. "#6366f1"
Accent string `json:"accent"` // --accent
AccentHover string `json:"accentHover"` // --accent-hover
AccentSoft string `json:"accentSoft"` // --accent-soft (rgba)
AccentRing string `json:"accentRing"` // --accent-ring (rgba)
OnPrimary string `json:"onPrimary"` // text color on accent bg
Glow string `json:"glow"` // --glow (rgba, for background accents)
Tint string `json:"tint"` // --tint (rgba, ~5% for sidebar/header)
AccentInk string `json:"accentInk"` // --accent-ink in dark mode
AccentInkLight string `json:"accentInkLight"` // --accent-ink in light mode
}
Theme holds a per-directory color palette derived from a user-chosen primary color.
Source Files
¶
- access_log.go
- appearance_routes.go
- board.go
- board_routes.go
- browser_routes.go
- config_routes.go
- docindex_routes.go
- event_routes.go
- feature_flags.go
- file_change_routes.go
- git_routes.go
- host_session.go
- install_event.go
- latex_fitz.go
- latex_routes.go
- lock_unix.go
- mcp_routes.go
- model_catalog.go
- model_routes.go
- note_routes.go
- ogx_routes.go
- permission_routes.go
- posthog.go
- preview.go
- preview_ports.go
- preview_services.go
- pricing_routes.go
- project_type.go
- projectlock.go
- provider_routes.go
- public.go
- query_sheet_loader.go
- question_routes.go
- reminder.go
- resource_routes.go
- resume_routes.go
- routes.go
- scrcpy.go
- server.go
- session_routes.go
- session_search_routes.go
- skills_routes.go
- static.go
- theme_routes.go
- usage_routes.go
- version_routes.go