codingagent

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 108 Imported by: 0

Documentation

Overview

Model picker auth-filter scope toggle.

AuthenticatedProviders + ReachableProviders are the single source of truth for "which providers can the user actually talk to right now" vs "which providers can ModelRuntime compose". Reachable is the whole built-in catalog plus ollama; authenticated is the subset whose credentials resolve from the environment, models.json, or auth.json.

Used by the interactive model surfaces (cycleModel, showScopedModels, --list-models) to default the picker scope to {auth ∩ reachable}.

Mirrors upstream pi-coding-agent's model-runtime.ts availability filter: upstream derives `available` from checkAuth() over the whole provider catalog, so pig derives both sets from the catalog rather than a hand-maintained provider list.

bash_executor.go: type aliases and shim for the !cmd interactive path.

User bash execution lives in internal/codingagent/tools/bash_executor.go (upstream core/bash-executor.ts executeBashWithOperations). This file re-exports its types so interactive code can call it without qualifying the tools sub-package.

Ports packages/coding-agent/src/core/resource-loader.ts

extensions.go defines extension event names and the TUI-backed UI surface:

  • Event name constants
  • ToolCallEventResult (agent loop hook)
  • ExtensionUIContext interface + NoopUI (headless fallback)
  • ExtensionContext (shared mutable state for the agent loop)
  • SlashCommand type (used by slash_commands.go)
  • TUIUIContext (interactive mode UI)

Ports packages/coding-agent/src/cli/file-processor.ts.

Ports packages/coding-agent/src/modes/interactive/interactive-mode.ts.

Ports packages/coding-agent/src/core/model-runtime.ts

Ports packages/coding-agent/src/core/provider-composer.ts

Ports packages/coding-agent/src/core/model-runtime.ts

Ports packages/coding-agent/src/modes/interactive/tui-renderer.ts.

Ports packages/coding-agent/src/core/model-runtime.ts Ports packages/coding-agent/src/core/provider-composer.ts

Ports packages/coding-agent/src/core/package-manager.ts (addAutoDiscoveredResources, collectAncestorAgentsSkillDirs, getHomeDir) and the ambient resource ordering of packages/coding-agent/src/core/resource-loader.ts reload.

Ports packages/coding-agent/src/config.ts

Ports packages/coding-agent/src/modes/interactive/components/session-selector.ts.

Ports packages/coding-agent/src/modes/interactive/components/session-selector.ts (deleteSessionFile).

Ports packages/coding-agent/src/modes/interactive/components/session-selector.ts (deleteSessionFile).

Ports packages/coding-agent/src/modes/interactive/components/session-selector.ts.

Ports packages/coding-agent/src/modes/interactive/components/settings-selector.ts (fullscreen-wheel-scroll-lines row).

Ports packages/coding-agent/src/core/skills.ts.

Ports packages/coding-agent/src/modes/interactive/interactive-mode.ts.

Ports packages/coding-agent/src/modes/interactive/interactive-mode.ts

Ports packages/coding-agent/src/core/tools/renderers/index.ts.

Index

Constants

View Source
const (
	// Session lifecycle
	EventSessionStart         = "session_start"
	EventSessionInfoChanged   = "session_info_changed"
	EventSessionShutdown      = "session_shutdown"
	EventSessionBeforeSwitch  = "session_before_switch"
	EventSessionBeforeFork    = "session_before_fork"
	EventSessionBeforeCompact = "session_before_compact"
	EventSessionCompact       = "session_compact"
	EventSessionCompactFailed = "session_compact_failed"
	EventSessionBeforeTree    = "session_before_tree"
	EventSessionTree          = "session_tree"

	// Agent loop
	EventAgentStart        = "agent_start"
	EventAgentEnd          = "agent_end"
	EventAgentBeforeSettle = "agent_before_settle"
	EventAgentSettled      = "agent_settled"
	EventTurnStart         = "turn_start"
	EventTurnEnd           = "turn_end"
	EventBeforeAgentStart  = "before_agent_start"
	EventMessageStart      = "message_start"
	EventMessageUpdate     = "message_update"
	EventMessageEnd        = "message_end"

	// Tools
	EventToolCall            = "tool_call"
	EventToolResult          = "tool_result"
	EventToolExecutionStart  = "tool_execution_start"
	EventToolExecutionUpdate = "tool_execution_update"
	EventToolExecutionEnd    = "tool_execution_end"

	// Context / provider
	EventContext               = "context"
	EventContextWithSystem     = "context_with_system"
	EventBeforeProviderRequest = "before_provider_request"
	EventAfterProviderResponse = "after_provider_response"
	EventBeforeProviderHeaders = "before_provider_headers"
	// EventProviderStreamEvent fires for a parsed provider stream event before normalization (types.ts ProviderStreamEvent).
	EventProviderStreamEvent = "provider_stream_event"

	// Models / input
	EventModelSelect         = "model_select"
	EventThinkingLevelSelect = "thinking_level_select"
	EventInput               = "input"
	// User-initiated bash command (`!cmd` / `!!cmd`).
	// Mirrors upstream `user_bash` event emitted by
	// `interactive-mode.ts:5040-5045::extensionRunner.emitUserBash`.
	// Payload: {type, command, excludeFromContext, cwd}.
	EventUserBash = "user_bash"

	// Resources
	EventResourcesDiscover = "resources_discover"

	// MCP servers registered by extensions (types.ts McpServersChangeEvent).
	EventMcpServersChange = "mcp_servers_change"
)

Extension event name constants: mirror upstream event type strings.

View Source
const APP_TITLE = "PiG"

pig divergence (D2): title says "PiG", not "pi": separate binary and config root.

View Source
const AppName = "pig"

AppName is the binary/CLI name, independent of the selected configuration directories.

View Source
const BugReportCustomEntryType = "pi.bug-report"

BugReportCustomEntryType is the session custom-entry type recorded after a report is written. It matches upstream so Pi and PiG read the same history.

View Source
const (

	// BugReportIssueURL is the PiG issue form that /bug links to. PiG
	// reports go to the PiG repository, never to Pi's report gateway (D62).
	BugReportIssueURL = "https://github.com/MichaelKinsy/PiG/issues/new"
)
View Source
const BuiltinPathPrefix = "builtin:"

BuiltinPathPrefix is the prefix of built-in tool and extension paths, such as `builtin:read` or `builtin:mcp`. Ports .upstream/v0.99.1/packages/coding-agent/src/core/source-info.ts:14-15.

View Source
const CLISourceName = "cli"

CLISourceName is upstream's source for a resource named on the command line (-e, --skill): resource-loader.ts records {source: "cli", scope: "temporary", origin: "top-level"} for it.

View Source
const CONFIG_DIR_NAME = "." + AppName

CONFIG_DIR_NAME is the default per-project config directory name.

View Source
const CurrentSessionVersion = 3

CurrentSessionVersion mirrors upstream `CURRENT_SESSION_VERSION = 3`. Pi schema migrations are applied by session_restore.go.

View Source
const DefaultCatalogBaseURL = "https://pi-in-go.dev"

DefaultCatalogBaseURL is the catalog endpoint of the built-in providers. pig divergence (D64): PiG reads the remote catalog overlay from its own pi-in-go.dev instead of Pi's https://pi.dev (remote-catalog-provider.ts:DEFAULT_CATALOG_BASE_URL). An endpoint that does not serve the catalog (404 or 501) leaves the bundled catalog.

View Source
const DefaultThinkingLevel = "medium"

DefaultThinkingLevel mirrors upstream's defaults.ts:

export const DEFAULT_THINKING_LEVEL: ThinkingLevel = "medium";

Used as the fallback when settings.json does not define defaultThinkingLevel. Thinking-level initialization consumes it.

If upstream ever changes the default, the tripwire test in defaults_test.go fails, surfacing the drift on the next sync.

View Source
const ENV_AGENT_DIR = "PIG_CODING_AGENT_DIR"

ENV_AGENT_DIR overrides the config directory. Mirrors upstream ENV_AGENT_DIR export.

View Source
const ENV_SESSION_DIR = "PIG_CODING_AGENT_SESSION_DIR"

ENV_SESSION_DIR overrides the session storage directory. Mirrors upstream ENV_SESSION_DIR export.

View Source
const EnvRadiusGateway = "PI_RADIUS_GATEWAY"

EnvRadiusGateway overrides the Radius gateway origin for GetRadiusGatewayURL. In Pi 0.87.1 only the experimental server and relay read it; the built-in provider always uses ai.DefaultRadiusGateway.

View Source
const LlamaExtensionPath = BuiltinPathPrefix + "llama.cpp"

LlamaExtensionPath is the source path upstream gives the built-in llama.cpp extension (`builtin:${name}`). Ports .upstream/v0.99.1/packages/coding-agent/src/extensions/index.ts:8 and core/resource-loader.ts:706-735.

View Source
const PackageName = "@pi-in-go/pig"

PackageName is PiG's npm package: the launcher that a global npm-family install owns and that the signed update manifest names. Mirrors upstream PACKAGE_NAME export. automation/release/pig_package.py reads this line, so keep the declaration on one line.

View Source
const RadiusProviderID = ai.RadiusProviderID

RadiusProviderID is the built-in Radius provider ID.

View Source
const RemoteCatalogRefreshInterval = 4 * time.Hour

RemoteCatalogRefreshInterval is how long a checked catalog stays fresh (remote-catalog-provider.ts:REMOTE_CATALOG_REFRESH_INTERVAL_MS).

View Source
const UpdateSignatureHeader = "X-Pig-Release-Signature"

UpdateSignatureHeader carries the base64 Ed25519 signature over the exact update manifest response bytes.

Variables

View Source
var CacheWarmingModes = []CacheWarmingMode{"off", "streaming", "idle"}

CacheWarmingModes lists the modes in Pi's order (CACHE_WARMING_MODES).

View Source
var CodemodeRenderers = ToolRenderers{RenderCall: codemodeRenderCall, RenderResult: codemodeRenderResult}

CodemodeRenderers draw the codemode tool's card: the call shows the script; the result lists the nested calls with their status and the cost of its model calls, followed by the script output without the "Script completed" header. The codemode tool definition carries them, as upstream's definition spreads codemodeRenderers; they are not built-in renderers keyed by tool name (upstream createAllToolRenderers has no codemode entry).

Ports packages/coding-agent/src/extensions/codemode/renderer.ts (codemodeRenderers).

View Source
var DefaultModelPerProviderOrder = []struct{ Provider, ModelID string }{
	{"amazon-bedrock", "us.anthropic.claude-opus-4-6-v1"},
	{"ant-ling", "Ring-2.6-1T"},
	{"anthropic", "claude-opus-4-8"},
	{"openai", "gpt-5.5"},
	{"azure", "gpt-5.4"},
	{"openai-codex", "gpt-6.1-sol"},
	{"radius", "balanced"},
	{"nvidia", "nvidia/nemotron-3-ultra-550b-a55b"},
	{"deepseek", "deepseek-v4-pro"},
	{"google", "gemini-3.1-pro-preview"},
	{"google-vertex", "gemini-3.1-pro-preview"},
	{"github-copilot", "gpt-5.4"},
	{"openrouter", "moonshotai/kimi-k2.6"},
	{"vercel-ai-gateway", "zai/glm-5.1"},
	{"xai", "grok-4.7"},
	{"groq", "openai/gpt-oss-120b"},
	{"cerebras", "gpt-oss-120b"},
	{"zai", "glm-5.3"},
	{"zai-coding-cn", "glm-5.3"},
	{"mistral", "devstral-medium-latest"},
	{"minimax", "MiniMax-M2.7"},
	{"minimax-cn", "MiniMax-M2.7"},
	{"moonshotai", "kimi-k2.6"},
	{"moonshotai-cn", "kimi-k2.6"},
	{"huggingface", "moonshotai/Kimi-K2.6"},
	{"fireworks", "accounts/fireworks/models/kimi-k3"},
	{"together", "moonshotai/Kimi-K3"},
	{"baseten", "zai-org/GLM-5.2"},
	{"opencode", "kimi-k2.6"},
	{"opencode-go", "kimi-k3"},
	{"kimi-coding", "kimi-for-coding"},
	{"meta", "muse-spark-1.3"},
	{"cloudflare-workers-ai", "@cf/moonshotai/kimi-k2.6"},
	{"cloudflare-ai-gateway", "workers-ai/@cf/moonshotai/kimi-k2.6"},
	{"qwen-token-plan", "qwen3.7-max"},
	{"qwen-token-plan-cn", "qwen3.7-max"},
	{"qwen-token-plan-individual", "qwen3.8-max"},
	{"xiaomi", "mimo-v2.5-pro"},
	{"xiaomi-token-plan-cn", "mimo-v2.5-pro"},
	{"xiaomi-token-plan-ams", "mimo-v2.5-pro"},
	{"xiaomi-token-plan-sgp", "mimo-v2.5-pro"},
}

DefaultModelPerProviderOrder preserves the declaration order used by findInitialModel.

View Source
var DefaultUpdateTrustRoot string

DefaultUpdateTrustRoot is an optional build-time Ed25519 public key in PEM form, or the same PEM base64-encoded on one line (a multi-line value cannot be passed through -ldflags -X). Distributor installers can instead seed the public key through the update-trust.pem sidecar beside update-url.

View Source
var DefaultUpdateURL string

DefaultUpdateURL is the built-in update-manifest URL. It is empty in stock pig and is set at build time for a product binary via:

-ldflags "-X github.com/MichaelKinsy/PiG/internal/codingagent.DefaultUpdateURL=<url>"

so a product release can configure its update source. PiG's own release builds (release-candidate.yml) point it at the latest release's signed update.json; development, go install, and Piglet builds leave it empty.

View Source
var ErrInteractiveCrashed = errors.New("interactive mode crashed")

ErrInteractiveCrashed reports that Run recovered a crash it already printed and recorded; the caller exits 1 without printing it again.

View Source
var ErrUnknownSlashCommand = errors.New("unknown slash command")

ErrUnknownSlashCommand signals that a slash command was not found in the registry. The caller should pass the original text to the LLM as a regular message (matches upstream behavior where unknown slashes are sent as-is).

View Source
var InstalledPigVersion string

InstalledPigVersion is the running Pig distribution version. cmd/pig sets it before dispatch so receipt validation can bind the executable to its release.

View Source
var PigletBinaryRelease string

PigletBinaryRelease is the baked Piglet/Piglet Binary release version. It is empty for stock Pig and set via ldflags for a Piglet Binary. When set it marks the running binary as an immutable baked release whose composition cannot be drifted in place (see ResolveSelfUpdateTier). It is the single source of truth for the baked release identity; cmd/pig copies its ldflags value here at startup.

RadiusMcpURL is the MCP endpoint of the gateway the built-in Radius provider signs in to (core/radius.ts:6).

RemoteCatalogModelTypes are the model types this client can consume. They are sent as `?types=` so the catalog server returns the full-type shard instead of the chat-only one served to clients that predate model types. A server that ignores the parameter still returns the chat-only shard, which this client handles unchanged. upstream: remote-catalog-provider.ts:14-19 (REMOTE_CATALOG_MODEL_TYPES)

View Source
var SupportedImageMIMEs = []string{
	"image/png",
	"image/jpeg",
	"image/webp",
	"image/gif",
}

SupportedImageMIMEs lists the formats we accept from the clipboard. Order = preference (matches upstream SUPPORTED_IMAGE_MIME_TYPES).

Functions

func ActiveExtensionTheme

func ActiveExtensionTheme() extension.Theme

ActiveExtensionTheme is the active theme as extensions see it (ctx.ui.theme): upstream hands every mode's UI context the global theme.

func AgentDir

func AgentDir() string

AgentDir returns the writable agent directory. Shared mode uses Pi's environment override; otherwise it uses PiG's. Both expand a leading tilde.

func AgentDirConfigured

func AgentDirConfigured() bool

AgentDirConfigured reports whether the agent directory comes from its environment variable rather than the default.

func AgentEventContext

func AgentEventContext(ev agent.AgentEvent) context.Context

AgentEventContext returns the context an extension handler for ev runs under. It carries the event's stream scope, so a handler that waits for its extension process releases the stream's continuation queue instead of freezing the provider, as Pi's awaited handler does (agent-session.ts:894-919; runner.ts:emit).

func AgentLoopEventType

func AgentLoopEventType(ev agent.AgentEvent) string

AgentLoopEventType returns the extension event type DispatchAgentLoopEvent dispatches for ev, or "" for an event it does not dispatch.

func AgentStateSystemPrompt

func AgentStateSystemPrompt(messages []agent.AgentMessage) string

AgentStateSystemPrompt returns upstream agent.state.systemPrompt: the prompt replayed from the transcript's system messages (agent.ts:89-91). It excludes a request-only forced prompt and base-prompt changes not yet sent to the model, which AgentSession.systemPrompt includes.

func AmbientPromptPaths

func AmbientPromptPaths(cwd, agentDir string, sm *SettingsManager, project bool) []string

AmbientPromptPaths lists the paths of AmbientPromptResources.

func AmbientSkillPaths

func AmbientSkillPaths(cwd, agentDir string, sm *SettingsManager, project, user bool) []string

AmbientSkillPaths lists the enabled skills that settings and auto-discovery yield once DefaultPackageManager.resolve has keyed each by its SKILL.md and reduced the first-wins accumulator, so an explicit exclusion disables an auto-discovered skill at the same path; a skill that Pi keys by its SKILL.md is listed by its directory (package-manager.ts:365-400, 927-961, 2555-2565).

func AreExperimentalFeaturesEnabled

func AreExperimentalFeaturesEnabled() bool

AreExperimentalFeaturesEnabled reports whether experimental features are on.

func AssertSessionCwdExists

func AssertSessionCwdExists(session *Session, fallbackCwd string) error

func AuthResultJSON

func AuthResultJSON(result *ai.AuthResult) map[string]any

AuthResultJSON is upstream's AuthResult object: auth with apiKey, headers and baseUrl when set, then env and source.

func AuthenticatedProviders

func AuthenticatedProviders(agentDir string) map[string]bool

AuthenticatedProviders returns the subset of ReachableProviders for which credentials are detectable in the environment / auth.json / model registry, without probing the network.

  • github-copilot / openai-codex: OAuth credential present with a refresh token (a half-completed login is not configured auth)
  • every other provider: its env API key, a models.json apiKey, or any stored auth.json credential (api_key or oauth)
  • ollama: OLLAMA_HOST env set (cheap heuristic; we do NOT probe localhost:11434: picking ollama with no daemon running is a user error caught at switch time)
  • amazon-bedrock: any AWS auth signal, including shared config files
  • google-vertex: GOOGLE_CLOUD_API_KEY or ADC (via hasEnvAuth)

agentDir is the pig config dir (typically ~/.pig/agent). auth.json and models.json are read from there.

func BugReportArchiveFileName

func BugReportArchiveFileName(id string) string

BugReportArchiveFileName names a report archive. Mirrors upstream bugReportArchiveFileName with PiG's command name (D2).

func BugReportIssueLink(metadata BugReportMetadata, archiveName, upstreamVersion string) string

BugReportIssueLink returns a prefilled PiG bug-form URL. It carries only the form's own fields: a title from the first line of the description (bounded), the PiG and Pi versions, the platform, and the archive name to attach. It never carries session content, settings, or paths.

func CanonicalizePath

func CanonicalizePath(path string) string

CanonicalizePath resolves a nonempty path to its absolute canonical filesystem form, following symlinks and drive junctions while preserving Windows volume mount points as directories. It preserves the raw input if resolution fails, including an empty or missing path. Mirrors upstream canonicalizePath.

func CatalogRoot

func CatalogRoot(agentDir string) string

CatalogRoot returns the managed catalog materialization root.

func CleanupWindowsSelfUpdateQuarantine

func CleanupWindowsSelfUpdateQuarantine(packageDir string)

CleanupWindowsSelfUpdateQuarantine removes the images an earlier npm self-update quarantined beside packageDir. A previous pig process may still be exiting and holding one, so a failure leaves the quarantine for the next start.

func ClearCrashLog

func ClearCrashLog(path string)

ClearCrashLog removes the crash log; a failure leaves the records for the next report. Mirrors upstream clearCrashLog.

func CompareChangelogEntries

func CompareChangelogEntries(a, b ChangelogEntry) int

CompareChangelogEntries returns -1, 0, or 1 mirroring upstream `compareVersions`. Callers use it to filter entries newer than a version.

func CompareVersions

func CompareVersions(a, b string) int

CompareVersions compares strict semantic versions. Returns -1 if a<b, 1 if a>b, and 0 when equal or when either side is malformed. Callers parsing release metadata must reject malformed remote versions before comparison; the zero fallback here keeps development/CI local versions non-disruptive.

func ConfigDirName

func ConfigDirName() string

ConfigDirName returns the selected per-project configuration directory name.

func ConfigRoot

func ConfigRoot() string

ConfigRoot returns the pig configuration root directory.

Resolution order:

  1. $PIG_HOME if set and non-empty
  2. $XDG_CONFIG_HOME/pig if XDG_CONFIG_HOME is set
  3. ~/.pig (default)

PiG-owned state stays here even when the agent and project directories are shared with Pi.

func ContainerRemediation

func ContainerRemediation(exePath string) string

ContainerRemediation is the exact authenticated pull/redeploy instruction for an OCI image or Piglet Image deployment. Raw Pig performs no transport and knows no product topology, so a deployment that owns a specific redeploy operation supplies it verbatim through PIG_REDEPLOY_INSTRUCTION. Pig still owns the surrounding facts (artifact identity, executable, and the guarantee that the running image is never rewritten); only the operation comes from the product. Without that metadata Pig falls back to the generic image pull, which is correct for a plain OCI/container install but not for an orchestrator-managed deployment.

func ConvertImageBytesToPng

func ConvertImageBytesToPng(data []byte) []byte

ConvertImageBytesToPng mirrors upstream convertImageBytesToPng: it decodes the image, applies its EXIF orientation, and re-encodes it as PNG. It returns nil when the bytes cannot be decoded or encoded, where upstream returns null (conversion failed or Photon unavailable).

func ConvertToPng

func ConvertToPng(base64Data, mimeType string) *tui.ConvertedImage

ConvertToPng mirrors upstream convertToPng: the Kitty graphics protocol requires PNG (f=100), so a non-PNG base64 image is converted. PNG input is returned unchanged; nil is upstream's null for a failed conversion.

func CopyToClipboard

func CopyToClipboard(text string) error

CopyToClipboard writes text to the system clipboard, for components outside this package such as the MCP sign-in screen.

func CrashLogPath

func CrashLogPath(agentDir string) string

CrashLogPath returns the crash log location for an agent directory.

func CreateAllToolRenderers

func CreateAllToolRenderers() map[string]ToolRenderers

CreateAllToolRenderers returns the shared built-in render functions, keyed by tool name. Each card supplies its own state and owns its background work.

func CreateInteractiveTui

func CreateInteractiveTui(options InteractiveTuiOptions) tui.Renderer

CreateInteractiveTui creates a regular or fullscreen renderer with the shared theme, clipboard and hyperlink behavior. It does not start terminal input or activate a Session.

func CreateShareTrailingEntries

func CreateShareTrailingEntries(state ShareState, parentID *string, timestamp string) []any

CreateShareTrailingEntries returns the trailing pi.share entry carrying the system prompt and tool schemas for the session viewer. Mirrors upstream createShareTrailingEntries.

func CurrentSystemMessage

func CurrentSystemMessage(messages []agent.AgentMessage) *ai.SystemMessage

CurrentSystemMessage replays every projected system message into the current prompt and tool state (pi-ai getCurrentSystemMessage).

func DefaultAgentDir

func DefaultAgentDir() string

DefaultAgentDir returns Pi's configured agent directory in shared mode, or <ConfigRoot>/agent otherwise.

func DefaultModelPerProvider

func DefaultModelPerProvider() map[string]string

DefaultModelPerProvider returns the defaults shared by startup and authentication.

func DefaultSkillsDir

func DefaultSkillsDir() string

DefaultSkillsDir returns the user agent's skills directory.

func DetectSupportedImageMimeType

func DetectSupportedImageMimeType(data []byte) string

func DiscoverAncestorAgentsSkillDirs

func DiscoverAncestorAgentsSkillDirs(startDir string) []string

DiscoverAncestorAgentsSkillDirs walks from startDir up to the git root (or filesystem root), collecting .agents/skills directories at each level (package-manager.ts collectAncestorAgentsSkillDirs).

func DiscoverPromptFile

func DiscoverPromptFile(cwd, agentDir, name string, projectTrusted bool) string

DiscoverPromptFile returns the SYSTEM.md or APPEND_SYSTEM.md file a loader reads: the workspace file when project resources are trusted, otherwise the agent directory file, or "" when neither exists (resource-loader.ts discoverSystemPromptFile, discoverAppendSystemPromptFile).

func DispatchAgentLoopEvent

func DispatchAgentLoopEvent(runner *inproc.Runner, ev agent.AgentEvent, currentMessage *extension.AgentMessage)

DispatchAgentLoopEvent maps one agent-loop event to the extension runner. Session awaits extension dispatch before notifying public listeners, as agent-session.ts::_handleAgentEvent does. Each message_update carries its own shallow message and full provider event; currentMessage retains the message_start value for callers that track it.

func ExpandPromptTemplate

func ExpandPromptTemplate(line string, templates []PromptTemplate) (string, bool)

ExpandPromptTemplate consumes a /name command separated from its arguments by ECMAScript whitespace. A matching template returns its expanded body and true; a non-command or unknown name returns an empty string and false. Upstream: packages/coding-agent/src/core/prompt-templates.ts:318-334.

func ExpandSkillCommand

func ExpandSkillCommand(text string, skills []*SkillDef) (string, bool, *extension.ExtensionError)

ExpandSkillCommand reads the selected skill at invocation time, strips frontmatter, and appends trimmed arguments. Unknown skills are not expanded. Read and parse errors leave input unchanged and carry a skill_expansion diagnostic. Ports packages/coding-agent/src/core/agent-session.ts (_expandSkillCommand).

func ExpandTildePath

func ExpandTildePath(path string) string

ExpandTildePath expands a leading ~ in a filesystem path. Mirrors upstream expandTildePath.

func ExportSessionForShare

func ExportSessionForShare(filePath string, session *Session, state ShareState) (string, error)

ExportSessionForShare writes the current branch with the export-only pi.share presentation entry. Mirrors upstream exportSessionForShare.

func ExportSessionToHTML

func ExportSessionToHTML(sessionFile, outputPath string, getToolRenderers func(name string) *extension.ToolRenderers, cwd string, state ShareState) (string, error)

ExportSessionToHTML writes the session file as HTML the way upstream exportSessionToHtml does and returns the path written. An in-memory session (empty sessionFile) and a session whose file is not written yet fail with upstream's messages. outputPath is normalized as upstream normalizePath does and written relative to the process working directory without creating its parent; an empty outputPath becomes pig-session-<session basename>.html. state is the live agent state upstream passes to exportSessionToHtml: the export embeds its system prompt and active tool schemas.

func ExportSessionToJsonl

func ExportSessionToJsonl(session *Session, outputPath string, createTrailingEntries TrailingEntries) (string, error)

ExportSessionToJsonl writes the session's current branch (and optional trailing entries) to outputPath, resolved against the process working directory, or to session-<ISO timestamp>.jsonl there when outputPath is empty. It returns the resolved path. Mirrors upstream exportSessionToJsonl.

func ExportToolRenderers

func ExportToolRenderers(runner *inproc.Runner) func(name string) *extension.ToolRenderers

ExportToolRenderers is upstream AgentSession's getToolRenderers for HTML exports: the resolvers of runner's extensions in load order, then the tools they registered. A nil runner draws no tool through renderers. upstream: packages/coding-agent/src/core/agent-session.ts:exportToHtml (getToolRenderers)

func ExtensionEntryIdentity

func ExtensionEntryIdentity(sess *Session, direct *subprocess.DirectEntryAppend) (string, string, error)

ExtensionEntryIdentity returns the id and timestamp of a custom entry an extension appends: those ctx.sessionManager.appendCustomEntry already generated in the extension process and returned, or new ones for pi.appendEntry. Upstream generates the id in the log's own process, checked against every existing id, so an id the log already holds is refused.

func ExtensionForImageMIME

func ExtensionForImageMIME(mime string) string

ExtensionForImageMIME returns the canonical file extension for a supported image MIME, or "" if unknown. Matches upstream's extensionForImageMimeType.

func ExtensionModelRegistryState

func ExtensionModelRegistryState(registry *ModelRegistry, catalog []*ai.Model) map[string]any

ExtensionModelRegistryState returns the registry snapshot for extension processes: the catalog under "models", each provider's display name, base URL, auth status, configured auth and OAuth use under "providers", and the registry error under "error". Upstream ModelRuntime keeps the same facts in its snapshot (all models, configured providers, auth checks) and answers getAll, getAvailable, hasConfiguredAuth, getProviderAuthStatus, getProvider, getProviderDisplayName, isUsingOAuth and getError from them.

func ExtensionSessionDir

func ExtensionSessionDir(override string) string

ExtensionSessionDir is the session directory a mode passes for its sessions: the --session-dir or configured directory as upstream SessionManager keeps it (utils/paths.ts normalizePath: a leading ~ and a file:// URL expand, any other path stays as given), or empty for the default.

func ExtensionSessionInfo

func ExtensionSessionInfo(view ExtensionSessionView) map[string]any

ExtensionSessionInfo is the header part of ReadonlySessionManager the Node runtime replicates with each state push.

func ExtensionSessionRead

func ExtensionSessionRead(view ExtensionSessionView, method string, args json.RawMessage) (any, error)

ExtensionSessionRead answers one ReadonlySessionManager read by its upstream method name. A result of nil is upstream's undefined or null.

func ExtensionThemePalette

func ExtensionThemePalette(theme *tui.Theme) extension.Theme

ExtensionThemePalette is the palette extensions receive for theme (ctx.ui.theme): its resolved escape sequences, and the host-resolved appearance and concrete colors.

func ExtensionToolInfos

func ExtensionToolInfos(runner ExtensionToolLister, allowed, excluded map[string]struct{}) []subprocess.ToolInfo

ExtensionToolInfos mirrors upstream AgentSession.getAllTools (agent-session.ts): the session's tool definition registry, not its active tools. Every built-in tool the --tools allowlist and --exclude-tools denylist admit is listed, active or not, in createAllToolDefinitions order; extension tools follow in registration order, first registration winning across extensions, and an extension tool named like a built-in takes that built-in's place (_refreshToolRegistry). --no-builtin-tools only changes the active set, so it lists the built-ins too.

allowed is nil when no allowlist is in force; an empty allowlist admits nothing, as --no-tools does.

func ExtensionsInLoadOrder

func ExtensionsInLoadOrder(configured, builtins []extension.Extension) []extension.Extension

ExtensionsInLoadOrder appends in-process builtins after configured extensions. Upstream resource-loader.ts loads path extensions first, then inline factories, and the runner preserves that order for dispatch and conflict ownership.

func FindExtensionStackMatches

func FindExtensionStackMatches(stack string, extensions []ExtensionStackMetadata) []string

FindExtensionStackMatches returns loaded extensions whose source files occur in stack frames.

func FormatCacheWarmingStatus

func FormatCacheWarmingStatus(status CacheWarmingStatus, now int64) string

FormatCacheWarmingStatus is the one-line status /session shows. now is a Unix millisecond time.

func FormatCacheWarmingUsage

func FormatCacheWarmingUsage(entry UsageEntry) string

FormatCacheWarmingUsage is the one-line transcript text for persisted cache-warming usage.

func FormatChangelogForChat

func FormatChangelogForChat(entries []ChangelogEntry) string

FormatChangelogForChat wraps the released entries for a plain Markdown output sink. The interactive command uses separate border, title and padded Markdown components.

func FormatCrashExtensionHint

func FormatCrashExtensionHint(extensionMatches []string) string

FormatCrashExtensionHint formats the warning shown for matching extensions.

func FormatMissingSessionCwdError

func FormatMissingSessionCwdError(issue SessionCwdIssue) string

func FormatMissingSessionCwdPrompt

func FormatMissingSessionCwdPrompt(issue SessionCwdIssue) string

func FormatNoAPIKeyFoundMessage

func FormatNoAPIKeyFoundMessage(provider string) string

func FormatNoModelSelectedMessage

func FormatNoModelSelectedMessage() string

func FormatNoModelsAvailableMessage

func FormatNoModelsAvailableMessage() string

func FormatPathRelativeToCwdOrAbsolute

func FormatPathRelativeToCwdOrAbsolute(filePath, cwd string) string

FormatPathRelativeToCwdOrAbsolute returns a slash-normalized path relative to cwd when possible, otherwise the cleaned absolute path.

func FormatTokens

func FormatTokens(n int) string

FormatTokens is footer.ts formatTokens for presentations outside the interactive footer.

func GenerateSessionID

func GenerateSessionID() (string, error)

GenerateSessionID returns a time-ordered UUIDv7 for a new session.

func GetCacheWarmingDelayMs

func GetCacheWarmingDelayMs(ttlMs int64) (int64, bool)

GetCacheWarmingDelayMs refreshes at 90% of the TTL while preserving at least ten seconds of margin. The bool is false when the TTL is too short.

func GetCwdRelativePath

func GetCwdRelativePath(filePath, cwd string) string

GetCwdRelativePath returns the path relative to cwd, with the platform separator as Pi's path.relative gives it, when filePath resolves inside cwd, or "" when it is outside cwd.

func GetDefaultSessionDirPath

func GetDefaultSessionDirPath(cwd, agentDir string) string

GetDefaultSessionDirPath derives storage from the selected agent directory, without consulting another configuration root.

func GetPackageDir

func GetPackageDir() string

GetPackageDir is the installation directory of a compiled pig: the directory holding the running executable, as upstream getPackageDir returns for a compiled binary. It returns "" when the executable cannot be located.

func GetProjectTrustParentPath

func GetProjectTrustParentPath(cwd string) string

GetProjectTrustParentPath returns the parent trust key, or "" at the root.

func GetProjectTrustPath

func GetProjectTrustPath(cwd string) string

GetProjectTrustPath returns the canonical trust key for a cwd.

func GetPromptCacheTtlMs

func GetPromptCacheTtlMs(model *ai.Model, options ai.StreamOptions) (int64, bool)

GetPromptCacheTtlMs returns the model's prompt-cache lifetime for the request's retention. Explicit retention wins over the environment; none or a missing tier has no lifetime.

func GetRadiusGatewayURL

func GetRadiusGatewayURL() string

GetRadiusGatewayURL returns the Radius gateway origin, honoring PI_RADIUS_GATEWAY. Like upstream's `??`, a set but empty value is used.

func GitInstallRoot

func GitInstallRoot(cwd, agentDir string, project bool) string

GitInstallRoot returns the managed Git checkout root for one settings scope.

func HasTrustRequiringProjectResources

func HasTrustRequiringProjectResources(cwd string) bool

HasTrustRequiringProjectResources reports whether cwd has project-local inputs governed by project trust. Project config entries are checked only in cwd; .agents/skills is checked from cwd through every ancestor. The user's ~/.agents/skills is global input and never requires project trust.

func ImmutableBinaryRemediation

func ImmutableBinaryRemediation(exePath string) string

ImmutableBinaryRemediation is the exact, non-looping instruction for a baked Piglet/Piglet Binary release. Pig does not drift the baked composition in place; the owning release is rebuilt and re-pulled.

func InvokeProviderStreamSimple

func InvokeProviderStreamSimple(ctx context.Context, id string, callback extension.ProviderStreamSimple, model *ai.Model, transcript ai.TranscriptContext, options ai.StreamOptions) (stream *ai.AssistantMessageEventStream, err error)

InvokeProviderStreamSimple is the shared dynamic-to-native callback boundary. The caller resolves request credentials before invoking it.

func IsContextOverflow

func IsContextOverflow(msg *agent.AssistantMessage, contextWindow int) bool

IsContextOverflow reports whether an assistant message represents a context overflow. It is pi-ai's isContextOverflow (ai.IsContextOverflow).

func IsLlamaCommand

func IsLlamaCommand(command extension.ResolvedCommand) bool

IsLlamaCommand reports whether command is the /llama command of the built-in llama.cpp extension. A mode runs it with its own command context instead of the extension handler.

func IsLocalPath

func IsLocalPath(value string) bool

IsLocalPath reports whether value is a local path rather than a package source, a built-in extension or a remote URL. Bare names, relative paths, and file URLs are local. Ports .upstream/v0.99.1/packages/coding-agent/src/utils/paths.ts:45-64 (a `builtin:` value names a built-in extension).

func IsRecoverableLength

func IsRecoverableLength(msg *agent.AssistantMessage, desiredMaxOutput int) bool

IsRecoverableLength reports whether a provider stopped for length before reaching the model's original output limit. The limit must be the model value before request-time context clamping. It is pi-ai's isRecoverableLength (ai.IsRecoverableLength).

func IsReplayable

func IsReplayable(model *ai.Model, options ai.StreamOptions) bool

IsReplayable reports whether replaying the request with a one-token output cap leaves its cache entry untouched. Anthropic's budget-based thinking derives budget_tokens from max_tokens, and Anthropic keys the message cache on that budget, so only adaptive thinking replays safely.

func IsRetryableError

func IsRetryableError(msg *agent.AssistantMessage, contextWindow int) bool

IsRetryableError reports whether an assistant message is a transient provider or transport error worth retrying. A context overflow is not retryable: compaction handles it. Mirrors upstream AgentSession._isRetryableError, which applies pi-ai's isContextOverflow and isRetryableAssistantError.

func IsStdoutTakenOver

func IsStdoutTakenOver() bool

IsStdoutTakenOver reports whether a takeover is currently active.

func IsSyntheticPath

func IsSyntheticPath(path string) bool

IsSyntheticPath reports whether path names no file: `builtin:<name>` or an angle-bracket path. Ports .upstream/v0.99.1/packages/coding-agent/src/core/source-info.ts:27-29.

func IsWSL

func IsWSL(getenv func(string) string, readFile func(string) ([]byte, error)) bool

IsWSL reports whether the process runs under Windows Subsystem for Linux, where Windows executables are reachable through interop. Ports utils/wsl.ts isWSL: WSL_DISTRO_NAME or WSLENV, else a /proc/version that names Microsoft or WSL. getenv and readFile are injected so tests never read the host.

func KeybindingsFile

func KeybindingsFile(agentDir string) string

func ListSkills

func ListSkills(skillsDir string) ([]string, error)

ListSkills enumerates skill directories under skillsDir, applying symlink dedup. Returns skill names (the directory basenames) sorted alphabetically. A skill directory is anything containing a `SKILL.md` file.

A skill can be linked from multiple configured roots. Resolve symlinks so the user sees one entry in the /skills selector.

func LoadEntriesFromFile

func LoadEntriesFromFile(path string) ([]json.RawMessage, error)

Ports packages/coding-agent/src/core/session-manager.ts (loadEntriesFromFile). LoadEntriesFromFile skips malformed and JSON-falsy lines and requires a session header before accepting records.

func LoadThemePaths

func LoadThemePaths(registry *tui.ThemeRegistry, paths []string, report func(error))

LoadThemePaths adds theme files and directories in upstream precedence order, the first theme of a name winning. Report receives each unreadable or invalid path.

func MarkPathIgnoredByCloudSync

func MarkPathIgnoredByCloudSync(path string)

MarkPathIgnoredByCloudSync best-effort marks a directory as ignored by cloud sync providers. Mirrors upstream markPathIgnoredByCloudSync.

func ModelNetworkEnabled

func ModelNetworkEnabled() bool

ModelNetworkEnabled mirrors ModelRuntime.modelNetworkEnabled (PI_OFFLINE === undefined). PIG_OFFLINE is Pig's product-neutral alias.

func NPMInstallRoot

func NPMInstallRoot(cwd, agentDir string, project bool) string

NPMInstallRoot returns the managed npm project for one settings scope.

func NormalizeExtensionPaths

NormalizeExtensionPaths resolves extension-discovered file URLs and local paths against the session cwd, without changing the extension attribution. Invalid URLs fail before callers update resource state, with Node's own error as Pi's bindExtensions throws it. Ports packages/coding-agent/src/core/resource-loader.ts

func NormalizePromptContent

func NormalizePromptContent(content []ai.UserContentBlock, autoResize bool, model *ai.Model, processImage imageprocessing.ProcessImageFunc) []ai.UserContentBlock

NormalizePromptContent applies the selected model's profile once, before new images enter history. Prompt failures become text hints, unlike tool results.

func NormalizeToolResultImages

func NormalizeToolResultImages(result agent.AgentToolResult, autoResize bool) agent.AgentToolResult

func OpenBrowser

func OpenBrowser(target string)

OpenBrowser opens target in the platform browser. The launch is best-effort, as upstream's: callers still present the target to the user, so a launcher failure is not reported. Ports packages/coding-agent/src/utils/open-browser.ts

func OpenExternalEditor

func OpenExternalEditor(ctx context.Context, initial string, configuredEditor string) (string, error)

OpenExternalEditor resolves the command with SettingsManager's precedence, writes initial into a tempfile, runs the editor with inherited stdio, and returns the file contents on success. On editor non-zero exit OR read error, returns initial unchanged plus a non-nil error.

The tempfile is always removed before this function returns.

Caller is responsible for:

  • restoring cooked-mode terminal before calling (so the editor's stdin/stdout/stderr inherit a usable TTY);
  • re-entering raw mode and triggering a full re-render after.

Reference: upstream openExternalEditor() in modes/interactive/interactive-mode.ts.

func PackageManagerHomeDir

func PackageManagerHomeDir() string

PackageManagerHomeDir prefers nonempty HOME on every platform. Otherwise it uses the platform home variable, including an explicit empty value, or the OS user database when that variable is absent.

func ParsePromptArgs

func ParsePromptArgs(s string) []string

ParsePromptArgs splits arguments using ECMAScript whitespace outside single- and double-quoted runs. Empty quoted strings are omitted, and backslashes are literal. Upstream: packages/coding-agent/src/core/prompt-templates.ts:24-55.

func PigletArtifactsDir

func PigletArtifactsDir() string

PigletArtifactsDir returns the managed Piglet artifact store.

func PigletRecordsDir

func PigletRecordsDir() string

PigletRecordsDir returns the managed Piglet record store. Records live outside Piglet discovery so they never masquerade as editable source.

func PigletsDir

func PigletsDir() string

PigletsDir returns the user-owned Piglet source directory.

func PlatformKey

func PlatformKey() string

PlatformKey returns the "<goos>/<goarch>" manifest key for the current platform.

func PngTranscoder

func PngTranscoder(base64Data, _ string) (string, bool)

PngTranscoder is upstream loadPngTranscoder's transcoder: base64 image data to oriented base64 PNG data, or false when the data does not decode.

func PrepareCLIImageAttachment

func PrepareCLIImageAttachment(data []byte, mime string) ([]byte, string, string, error)

func PrepareWindowsNpmSelfUpdate

func PrepareWindowsNpmSelfUpdate(exePath string) error

PrepareWindowsNpmSelfUpdate readies the npm installation holding exePath for npm to replace: it clears an earlier quarantine and quarantines the images this process loaded from it, which for pig is the running executable. It does nothing outside Windows.

func ProjectConfigDir

func ProjectConfigDir(cwd string) string

ProjectConfigDir returns the selected workspace-local configuration root.

func ProjectStateDir

func ProjectStateDir(cwd, namespace string) string

ProjectStateDir returns one additive capability's workspace-scoped state directory.

func ProviderLoginHelp

func ProviderLoginHelp() string

ProviderLoginHelp mirrors upstream auth-guidance.ts.

func QuarantineWindowsNativeDependencies

func QuarantineWindowsNativeDependencies(packageDir string) error

QuarantineWindowsNativeDependencies moves each image this process loaded from packageDir into the quarantine and copies it back. Windows lets a loaded image be renamed but not overwritten or deleted, so the copy leaves npm free to replace packageDir while this process runs.

func RFC3339NowNano

func RFC3339NowNano() string

RFC3339NowNano returns the current UTC time in Pi's millisecond ISO format.

func RawStdoutWriter

func RawStdoutWriter() io.Writer

RawStdoutWriter returns an `io.Writer` that writes to the pre-takeover stdout. Convenient for passing into helpers like `printToolsForMessages` that expect a Writer interface.

func ReachableProviders

func ReachableProviders() map[string]bool

ReachableProviders returns the set of provider IDs that ModelRuntime can compose: every provider in the built-in catalog plus ollama, which is configured from the environment rather than declared in the catalog.

coding.BuildModel's buildProviderForEntry switches on a provider's API kind, not its id, so every catalog provider is wireable. Deriving this from the catalog keeps a new upstream provider from being silently omitted from the picker.

func ReadClipboardImage

func ReadClipboardImage() ([]byte, string, error)

ReadClipboardImage reads a PNG/JPEG/WebP/GIF from the system clipboard. Returns (nil, "", nil) when the clipboard holds no image : this is not an error case, just "nothing to paste".

func ReadClipboardImageContext

func ReadClipboardImageContext(parent context.Context) ([]byte, string, error)

ReadClipboardImageContext reads command backends before the native helper on Linux and the native helper directly elsewhere. Termux reads no image clipboard. Native transfer errors propagate unchanged, and unsupported formats are converted to PNG. The caller owns cancellation and awaits the transfer.

func ReadNativeProviderModelData

func ReadNativeProviderModelData(r *ModelRegistry)

ReadNativeProviderModelData reads the catalog of every provider whose models come from provider code, in provider order, and discards the models. A caller that has no use for the composed models but must still run the provider callbacks Pi's getModels runs uses it. The catalogs of the other providers are static data whose read has no effect to observe.

func RedactBugReportJSON

func RedactBugReportJSON(value any) (any, error)

RedactBugReportJSON copies a JSON-encodable value, replacing the value of every sensitive key with "<redacted>" and redacting URLs in strings. Mirrors upstream redactJsonValue.

func RedactBugReportURL

func RedactBugReportURL(value string) string

RedactBugReportURL strips credentials and secret-looking query parameters from an absolute URL, including a URL nested after a scheme prefix such as "git:https://...". Other strings are returned unchanged. Mirrors upstream redactUrl.

func RenderLoginHeader

func RenderLoginHeader(definition extension.ValidatedLoginDefinition, width int, options LoginHeaderOptions) []string

RenderLoginHeader renders a validated definition with Pig's fixed native login template. It is local and deterministic; callers choose terminal color and glyph capabilities before rendering.

func RenderTreeASCII

func RenderTreeASCII(root *SessionTreeNode) string

RenderTreeASCII renders a SessionTreeNode as an ASCII tree. Exported wrapper so the coding package can produce /tree output without duplicating the renderer.

func ReportDiagnostics

func ReportDiagnostics(diagnostics []AgentSessionRuntimeDiagnostic)

ReportDiagnostics writes diagnostics to stderr for non-interactive modes: "Error: " in red, "Warning: " in yellow, and info dimmed, colored only when stderr is a terminal. Mirrors upstream main.ts reportDiagnostics.

func ResolvePath

func ResolvePath(input, baseDir string) (string, error)

ResolvePath normalizes input and baseDir, then resolves the input to an absolute path. An empty baseDir uses the process working directory. Invalid file URLs return an error. Ports packages/coding-agent/src/utils/paths.ts:102-106.

func ResolvePromptInput

func ResolvePromptInput(input, description string) string

ResolvePromptInput returns the BOM-stripped contents of the file input names, or input itself when no such file exists or it cannot be read (resource-loader.ts resolvePromptInput).

func ResourcePaths

func ResourcePaths(resources []ResolvedResource) []string

ResourcePaths lists the paths of the enabled resources.

func ResourcePrecedenceRank

func ResourcePrecedenceRank(metadata PathMetadata) int

ResourcePrecedenceRank is package-manager.ts resourcePrecedenceRank: project settings entries, project auto-discovered, user settings entries, user auto-discovered, then Package resources.

func ResourcesDiscoverReason

func ResourcesDiscoverReason(sessionStartReason string) string

ResourcesDiscoverReason maps a session_start reason to the resources_discover reason. Pi's AgentSession passes "reload" for a reload and "startup" for every other Session start, including one a replacement created (agent-session.ts:2941; the union is "startup" | "reload", extensions/types.ts:551-555).

func RestoreStdout

func RestoreStdout()

RestoreStdout undoes a `TakeOverStdout`. Closes the pipe writer (signalling the copy goroutine to drain + exit), waits for the goroutine, then restores `os.Stdout`. Safe to call without a matching takeover (no-op).

func RunInputHandlers

func RunInputHandlers(ctx context.Context, runner *inproc.Runner, text string, images []ai.ImageContent, source extension.InputSource, streamingBehavior string) (string, []ai.ImageContent, bool, error)

RunInputHandlers runs the extension input handlers for user input and returns the text and images to use, or handled when an extension consumed it. A transform without images keeps the original images, and a handler failure is returned for the caller to report. Mirrors upstream agent-session.ts _runInputHandlers; coding.Session.RunInputHandlers is the Session entry point every mode uses.

func RunMigrations

func RunMigrations(cwd, agentDir string) (migratedAuthProviders []string, deprecationWarnings []string, err error)

RunMigrations runs the startup migrations, including the persisted keybinding-name rewrite. Auth writes return errors; malformed or unwritable keybindings are left alone, as in upstream runMigrations.

func RunPackageManagerUpdate

func RunPackageManagerUpdate(cmd *SelfUpdateCommand) error

RunPackageManagerUpdate executes the owning manager's update command. It is the only mutation path for the package-manager tier; once it starts, a failure surfaces from this tier and never falls through to another.

func SaveClipboardImageToTempFile

func SaveClipboardImageToTempFile(bytes []byte, mime string) (string, error)

SaveClipboardImageToTempFile writes the bytes to $TMPDIR/pig-clipboard-<nanos>.<ext> and returns the absolute path. The caller is responsible for cleanup; for a paste-into-editor flow we leave the file around so the model can read it back.

func SelectStartupSession

func SelectStartupSession(
	currentLoader func(SessionListOptions) ([]SessionInfo, error),
	allLoader func(SessionListOptions) ([]SessionInfo, error),
	opts StartupUIOptions,
) (path string, selected bool, err error)

SelectStartupSession runs the same session selector used by /resume before cwd-bound runtime services exist. Loaders run off the input owner, receive cancellation and progress options, and settle before teardown returns. Confirmed deletion tries trash before unlink; renaming is unavailable. It returns selected=false on cancellation.

func SelfReplace

func SelfReplace(ctx context.Context, client *http.Client, bin UpdateBinary) error

SelfReplace downloads bin, verifies its SHA256, and atomically replaces the running executable. Unix-only: replacing a running .exe in place needs the Windows quarantine dance pig does not implement, so on Windows it returns an error directing the user to reinstall.

func SelfReplaceAt

func SelfReplaceAt(ctx context.Context, client *http.Client, bin UpdateBinary, exePath string) error

SelfReplaceAt downloads bin, verifies its SHA256, and atomically replaces the executable at exePath. It is the standalone-tier replacement entry point used after tier resolution has proven exePath. Unix-only: on Windows it returns an error directing the user to reinstall. Concurrent replacements of the same executable fail before downloading.

func SelfReplaceAtWithCommit

func SelfReplaceAtWithCommit(
	ctx context.Context,
	client *http.Client,
	bin UpdateBinary,
	exePath string,
	commit func() error,
) error

SelfReplaceAtWithCommit replaces exePath and then commits its ownership metadata. If commit fails, the previous executable is restored before the error returns, so a failed receipt update cannot strand a new binary with stale provenance. Concurrent replacements of the same executable fail before downloading; the installation lock remains held through commit or rollback.

func SelfUpdateFallback

func SelfUpdateFallback() string

SelfUpdateFallback is the actionable instruction shown when self-update cannot run automatically (no source, unreachable, unsupported platform, or a read-only install). It degrades gracefully: point at the working command when a source is configured, otherwise the ladder of set-a-URL / download / pull the container image.

func SerializeSessionBranch

func SerializeSessionBranch(header SessionHeader, branch []SessionEntry, now time.Time, createTrailingEntries TrailingEntries) (string, error)

SerializeSessionBranch writes a fresh session header, the current branch with each entry's parentId chained to the previous entry, and any trailing entries, one JSON object per line. Mirrors upstream serializeSessionBranch.

func SessionEntryToContextMessages

func SessionEntryToContextMessages(entry SessionEntry) []agent.AgentMessage

SessionEntryToContextMessages projects one entry into context messages before context edits (session-manager.ts sessionEntryToContextMessages). State-only entries project to nothing.

func SettingsFileExists

func SettingsFileExists(agentDir string) bool

SettingsFileExists reports whether agentDir holds settings.json: Pi's first-time setup test (startup-ui.ts:139).

func ShowStartupInput

func ShowStartupInput(title, placeholder string, opts StartupUIOptions) (value string, selected bool, err error)

ShowStartupInput displays the extension text-input surface before runtime services exist. It returns selected=false when the user cancels.

func ShowStartupSelector

func ShowStartupSelector(title string, options []string, opts StartupUIOptions) (index int, selected bool, err error)

ShowStartupSelector displays a small pre-runtime choice list. It returns selected=false when the user cancels.

func SkillDiagnostics

func SkillDiagnostics(skill *SkillDef) []string

SkillDiagnostics validates a skill against the Agent Skills metadata rules. A missing description prevents model discovery; other findings are warnings.

func StartupKeybindHints

func StartupKeybindHints(km *KeybindingsManager) string

StartupKeybindHints renders the compact keybinding hint line shown under the startup banner, mirroring upstream interactive-mode's compact startup instructions (interrupt · clear/exit · / commands · ! bash · <expand> more). Keys resolve through the supplied manager so user remaps are reflected; a nil manager falls back to the built-in defaults.

func StateDir

func StateDir(namespace string) string

StateDir returns one additive capability's user-scoped state directory. Namespaces are code-owned identifiers, not user-provided paths.

func SubstitutePromptArgs

func SubstitutePromptArgs(content string, args []string) string

SubstitutePromptArgs returns content with `$1`, `${1:-default}`, `${@:N:L}`, `${@:-default}`, `$ARGUMENTS`, `$@` expanded against args. Mirrors upstream `substituteArgs` (core/prompt-templates.ts). A `:-default` value is used when the target arg is missing or empty. Substitution runs in a single pass, so argument values are NOT re-scanned for `$N`/`$@`/`$ARGUMENTS` patterns.

func SyntheticPathSource

func SyntheticPathSource(path string) string

SyntheticPathSource is the source of a path that names no file: "builtin" for `builtin:<name>`, or the prefix of an angle-bracket path such as "inline" for `<inline:name>`. It is empty for file paths. Ports .upstream/v0.99.1/packages/coding-agent/src/core/source-info.ts:17-25.

func SystemMessageFromAgentMessage

func SystemMessageFromAgentMessage(message agent.AgentMessage) (ai.SystemMessage, bool)

SystemMessageFromAgentMessage reads a projected system-role message.

func SystemPromptSkills

func SystemPromptSkills(skills []*SkillDef) []extension.SystemPromptSkill

SystemPromptSkills is the Skill shape Pi hands extensions in systemPromptOptions.skills (skills.ts Skill).

func TakeOverStdout

func TakeOverStdout() error

TakeOverStdout redirects subsequent `os.Stdout` writes to `os.Stderr`. Idempotent: a second call before `RestoreStdout` is a no-op. The saved original stdout is reachable via `WriteRawStdout` for explicit framed-output callers.

func ToolResultEventContent

func ToolResultEventContent(result agent.AgentToolResult) []any

ToolResultEventContent preserves text and images at the extension boundary.

func ToolResultEventOverride

func ToolResultEventOverride(result *extension.ToolResultEventResult) agent.AfterToolCallResult

ToolResultEventOverride decodes the runner's complete, chained content without coalescing text or moving images. An empty array clears the prior content.

func TopLevelResourcePaths

func TopLevelResourcePaths(autoDir string, entries []string, kind packagecontent.Kind) []string

TopLevelResourcePaths lists a scope's settings entries, then its auto-discovered resources, as package-manager.ts resourcePrecedenceRank orders them.

func UnsupportedRemediation

func UnsupportedRemediation(exePath string) string

UnsupportedRemediation is the concrete reinstall/download instruction for a read-only, Windows, or unknown-provenance installation. It never repeats the failed self-update command.

func UpdateSourceURL

func UpdateSourceURL() string

UpdateSourceURL resolves the update-manifest URL. Resolution order:

  1. PIG_UPDATE_URL env (explicit per-invocation override);
  2. a sidecar file at <config-root>/update-url, written by an installer that knows its origin at install time (a generic, transport-neutral seam: any distributor may write it; pig reads only the URL, never product data);
  3. the build-time embedded DefaultUpdateURL, set by a product release build;
  4. empty (no update source configured).

The sidecar lets an installer seed the update source for a downloaded binary without a Go toolchain (the binary is not rebuilt) and without modifying the user's shell rc. It carries one URL line; pig never writes it.

func UsePiDirs

func UsePiDirs() bool

UsePiDirs reports whether the user explicitly selected Pi's configuration directories.

func WireModelOperations

func WireModelOperations(bridge ModelOperationBridge, bindings ModelOperationBindings) func()

WireModelOperations installs one Session-owned extension model surface and returns its catalog-listener detach function.

func WithRemoteCatalog

func WithRemoteCatalog(provider *ai.ModelsProvider, catalogBaseURL string, localGeneratedAt *float64) *ai.ModelsProvider

WithRemoteCatalog adds a persisted catalog overlay to a static built-in provider. localGeneratedAt is the generation time, in Unix milliseconds, of the bundled catalog; nil means a stored catalog is always newer. upstream: remote-catalog-provider.ts:62-168 (withRemoteCatalog)

func WithoutHiddenSnippets

func WithoutHiddenSnippets(snippets map[string]string, hidden map[string]struct{}) map[string]string

WithoutHiddenSnippets returns snippets without the tools whose declarations the loadout hides (agent-session.ts:1674-1677). It returns the map itself when nothing is hidden.

func WriteBugReportArchive

func WriteBugReportArchive(bundle BugReportBundle, path string) (err error)

WriteBugReportArchive writes the bundle as a deflated zip at path. The file is created exclusively so an existing file is never overwritten.

func WriteRawStdout

func WriteRawStdout(text string) (int, error)

WriteRawStdout writes `text` to the original (pre-takeover) stdout, bypassing the redirect. Use for explicit framed output: print-mode final text, RPC JSON-RPC frames. When no takeover is active, this is equivalent to writing directly to `os.Stdout`.

func WriteStandaloneReceipt

func WriteStandaloneReceipt(exe, version, source string) error

WriteStandaloneReceipt atomically records a verified standalone install. Installers create the initial receipt; a successful standalone update replaces it with the newly installed release and digest.

Types

type AgentSessionRuntimeDiagnostic

type AgentSessionRuntimeDiagnostic struct {
	Type    string
	Message string
}

AgentSessionRuntimeDiagnostic is one startup diagnostic. Type is "info", "warning", or "error". Mirrors upstream AgentSessionRuntimeDiagnostic.

func CollectSettingsDiagnostics

func CollectSettingsDiagnostics(settingsManager *SettingsManager) []AgentSessionRuntimeDiagnostic

CollectSettingsDiagnostics drains the manager's settings errors as warnings naming the settings file, or the scope when no file backs the error. Mirrors upstream collectSettingsDiagnostics.

func DeduplicateDiagnostics

func DeduplicateDiagnostics(diagnostics []AgentSessionRuntimeDiagnostic) []AgentSessionRuntimeDiagnostic

DeduplicateDiagnostics removes duplicate type/message diagnostics while preserving their first occurrence. Startup and runtime settings managers can report the same file error. Mirrors upstream deduplicateDiagnostics.

type BashExecOptions

type BashExecOptions = tools.BashExecOptions

BashExecOptions is a type alias for tools.BashExecOptions.

type BashExecutionEntry

type BashExecutionEntry struct {
	SessionEntryBase
	Role               string `json:"-"` // always "bashExecution"; set on read
	Command            string `json:"-"`
	Output             string `json:"-"`
	ExitCode           *int   `json:"-"`
	Cancelled          bool   `json:"-"`
	Truncated          bool   `json:"-"`
	FullOutputPath     string `json:"-"`
	ExcludeFromContext bool   `json:"-"`
	MessageTimestamp   int64  `json:"-"`
}

BashExecutionEntry persists a user shell invocation as a message with role bashExecution, matching packages/coding-agent/src/core/session-manager.ts:appendMessage. ExcludeFromContext retains the entry in the transcript but excludes it from LLM conversion.

func (BashExecutionEntry) MarshalJSON

func (b BashExecutionEntry) MarshalJSON() ([]byte, error)

MarshalJSON serializes to upstream's wire shape (type:"message" + nested).

func (*BashExecutionEntry) UnmarshalJSON

func (b *BashExecutionEntry) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts BOTH the new wire shape (type:"message" with inner role:"bashExecution") AND the legacy pig shape (type:"bash_execution" with flat top-level fields), so older session files still load.

type BashExecutionMessage

type BashExecutionMessage struct {
	Role               string `json:"role"` // "bashExecution"
	Command            string `json:"command"`
	Output             string `json:"output"`
	ExitCode           *int   `json:"exitCode,omitempty"`
	Cancelled          bool   `json:"cancelled"`
	Truncated          bool   `json:"truncated"`
	FullOutputPath     string `json:"fullOutputPath,omitempty"`
	Timestamp          int64  `json:"timestamp"`
	ExcludeFromContext bool   `json:"excludeFromContext,omitempty"`
}

BashExecutionMessage is the inner `message` payload upstream uses for bash entries. Mirrors messages.ts:29-43 byte-for-byte.

type BashResult

type BashResult = tools.BashResult

BashResult is a type alias for tools.BashResult. All fields are identical; existing callers compile without changes.

func ExecuteBash

func ExecuteBash(ctx context.Context, command, cwd string, shell tools.ShellConfig, opts BashExecOptions) (BashResult, error)

ExecuteBash runs command under shell in cwd. Delegates to tools.ExecuteBash. See tools/bash_executor.go for the canonical implementation.

type BeforeAgentStartRun

type BeforeAgentStartRun struct {
	// Options are the options the handlers shared, or the base options when no handler changed them.
	Options extension.BuildSystemPromptOptions
	// SelectedTools is an explicit selectedTools edit, which becomes the run's tool loadout. Nil keeps the live active tools, including a handler's setActiveTools call.
	SelectedTools []string
	// Sections are the run's validated custom prompt sections, or nil.
	Sections ai.OrderedSections
	// SystemPrompt is the exact replacement a handler returned, or nil.
	SystemPrompt *string
	// Messages are the custom messages the handlers returned.
	Messages []extension.CustomMessageRef
}

BeforeAgentStartRun holds one prompt's per-run inputs after before_agent_start. The Session and interactive mode both derive their run from it.

func ResolveBeforeAgentStartRun

ResolveBeforeAgentStartRun applies agent-session.ts:1702-1714 to the options passed to before_agent_start and the combined result, which may be nil. A selectedTools list that differs from the base list is an explicit edit. Invalid section names fail as in system-prompt.ts buildSystemPromptSections; the returned run then carries only SelectedTools, because agent-session.ts:1409-1419 admits the loadout before it builds the sections, so the caller applies it before rejecting the prompt.

func (BeforeAgentStartRun) BaseSections

func (r BeforeAgentStartRun) BaseSections(selectedTools []string, hidden map[string]struct{}) ai.OrderedSections

BaseSections builds the run's structured prompt sections from the run's options, as _preparePromptAndToolLoadout does for every mode (agent-session.ts:1669-1683), before its custom sections apply. selectedTools are the live active tools. Snippets of hidden declarations are not listed, so the tool list matches the declarations the request carries (agent-session.ts:1674-1677).

func (BeforeAgentStartRun) NextTurnOptions

NextTurnOptions refreshes a run's options before a later turn: the live tools, and the base snippets and guidelines under the run's (agent-session.ts:697-706), so a tool registered during the run is listed and an edited entry wins.

func (BeforeAgentStartRun) PromptSections

func (r BeforeAgentStartRun) PromptSections(selectedTools []string, hidden map[string]struct{}) (ai.OrderedSections, error)

PromptSections is BaseSections with the run's validated custom sections applied.

type BinaryUpdate

type BinaryUpdate struct {
	CurrentVersion string
	LatestVersion  string
	Notes          string // release note text; a bare URL is ChangelogURL instead
	ChangelogURL   string
	Binary         UpdateBinary
	Command        string // the command that applies it, e.g. "pig update self"
}

BinaryUpdate describes an available newer release for the current platform.

func CheckForBinaryUpdate

func CheckForBinaryUpdate(ctx context.Context, client *http.Client, currentVersion string) *BinaryUpdate

CheckForBinaryUpdate fetches the update manifest and reports a newer release for the current platform, or nil when up to date, no source is configured, or the source is unreachable. It never surfaces an error: a startup update check is best-effort and must not disrupt the session. Any non-empty PI_SKIP_VERSION_CHECK disables this startup check without a request; explicit `pig update` does not call it.

type BranchSummaryConfig

type BranchSummaryConfig struct {
	ReserveTokens int  `json:"reserveTokens,omitempty"`
	SkipPrompt    bool `json:"skipPrompt,omitempty"`
	// contains filtered or unexported fields
}

BranchSummaryConfig mirrors compaction.BranchSummarySettings but lives here to avoid an import cycle.

type BranchSummaryEntry

type BranchSummaryEntry struct {
	SessionEntryBase
	FromID   string    `json:"fromId"`
	Summary  string    `json:"summary"`
	Details  any       `json:"details,omitempty"`
	FromHook bool      `json:"fromHook,omitempty"`
	Usage    *ai.Usage `json:"usage,omitempty"`
}

type BugReportAssistantDiagnostic

type BugReportAssistantDiagnostic struct {
	EntryID       string                          `json:"entryId"`
	Timestamp     string                          `json:"timestamp"`
	Provider      string                          `json:"provider"`
	Model         string                          `json:"model"`
	API           string                          `json:"api"`
	StopReason    string                          `json:"stopReason"`
	RawStopReason string                          `json:"rawStopReason,omitempty"`
	ErrorMessage  string                          `json:"errorMessage,omitempty"`
	Diagnostics   []ai.AssistantMessageDiagnostic `json:"diagnostics"`
}

BugReportAssistantDiagnostic is one failed or diagnosed assistant turn.

type BugReportAuthStatus

type BugReportAuthStatus struct {
	Configured bool   `json:"configured"`
	Source     string `json:"source,omitempty"`
	Label      string `json:"label,omitempty"`
}

BugReportAuthStatus mirrors upstream's provider auth status record.

type BugReportBundle

type BugReportBundle struct {
	Metadata     BugReportMetadata
	Diagnostics  BugReportDiagnostics
	SessionJSONL *string
	Summary      *string
}

BugReportBundle is everything one report archive contains.

type BugReportDiagnostics

type BugReportDiagnostics struct {
	SchemaVersion         int                            `json:"schemaVersion"`
	SessionID             string                         `json:"sessionId"`
	EntryCount            int                            `json:"entryCount"`
	AssistantMessageCount int                            `json:"assistantMessageCount"`
	Assistant             []BugReportAssistantDiagnostic `json:"assistant"`
	Crashes               []CrashRecord                  `json:"crashes"`
}

BugReportDiagnostics is diagnostics.json.

func CollectBugReportDiagnostics

func CollectBugReportDiagnostics(sessionID string, entries []SessionEntry, crashes []CrashRecord) BugReportDiagnostics

CollectBugReportDiagnostics collects failed assistant turns without conversation content, plus the crash log records without their notified flag. Mirrors upstream collectBugReportDiagnostics.

type BugReportEnvironment

type BugReportEnvironment struct {
	Version   string               `json:"version"`
	UserAgent string               `json:"userAgent"`
	Runtime   string               `json:"runtime"`
	Platform  string               `json:"platform"`
	Arch      string               `json:"arch"`
	OSRelease string               `json:"osRelease"`
	OSVersion string               `json:"osVersion"`
	Shell     *string              `json:"shell"`
	Terminal  BugReportTerminalEnv `json:"terminal"`
	// PiEnvironmentVariables lists PI_* names only; values never leave the
	// machine. PigEnvironmentVariables lists PiG's own PIG_* names.
	PiEnvironmentVariables  []string `json:"piEnvironmentVariables"`
	PigEnvironmentVariables []string `json:"pigEnvironmentVariables"`
}

BugReportEnvironment describes the running PiG process without secrets.

type BugReportExtension

type BugReportExtension struct {
	Path string `json:"path"`
}

BugReportExtension describes one loaded extension by its resolved path.

type BugReportExtensionError

type BugReportExtensionError struct {
	Error string `json:"error"`
}

BugReportExtensionError is one extension load failure. PiG's subprocess host reports failures as messages without a separate path.

type BugReportFile

type BugReportFile struct {
	Name string
	Data []byte
}

BugReportFile is one archive member.

func BugReportFiles

func BugReportFiles(bundle BugReportBundle) ([]BugReportFile, error)

BugReportFiles lists the archive members in upstream order.

type BugReportInputs

type BugReportInputs struct {
	Version         string
	SessionID       string
	CWD             string
	MessageCount    int
	Model           *ai.Model
	Provider        *BugReportProvider
	ThinkingLevel   string
	ExtensionPaths  []string
	ExtensionErrors []string
	GlobalSettings  Settings
	ProjectSettings Settings
	Entries         []SessionEntry
	Branch          []SessionEntry
	Header          SessionHeader
}

BugReportInputs is the process state a report describes. The interactive host fills it; tests construct it directly.

type BugReportMetadata

type BugReportMetadata struct {
	SchemaVersion   int                       `json:"schemaVersion"`
	ID              string                    `json:"id"`
	CreatedAt       string                    `json:"createdAt"`
	Hint            *string                   `json:"hint"`
	Environment     BugReportEnvironment      `json:"environment"`
	Session         BugReportSessionInfo      `json:"session"`
	Model           *BugReportModel           `json:"model"`
	Provider        *BugReportProvider        `json:"provider"`
	ThinkingLevel   string                    `json:"thinkingLevel"`
	Extensions      []BugReportExtension      `json:"extensions"`
	ExtensionErrors []BugReportExtensionError `json:"extensionErrors"`
	Settings        BugReportSettings         `json:"settings"`
}

BugReportMetadata is report.json. Field order follows upstream.

func CollectBugReportMetadata

func CollectBugReportMetadata(inputs BugReportInputs, options BugReportOptions, summaryIncluded bool, now time.Time) (BugReportMetadata, error)

CollectBugReportMetadata builds report.json. Mirrors upstream collectBugReportMetadata.

type BugReportModel

type BugReportModel struct {
	Provider         string              `json:"provider"`
	ID               string              `json:"id"`
	Name             string              `json:"name"`
	API              string              `json:"api"`
	BaseURL          string              `json:"baseUrl"`
	Reasoning        bool                `json:"reasoning"`
	Input            []string            `json:"input"`
	ContextWindow    int                 `json:"contextWindow"`
	MaxTokens        int                 `json:"maxTokens"`
	SamplingParams   any                 `json:"samplingParams"`
	Compat           any                 `json:"compat"`
	ThinkingLevelMap ai.ThinkingLevelMap `json:"thinkingLevelMap"`
	HeaderNames      []string            `json:"headerNames"`
}

BugReportModel describes the current model without credentials.

type BugReportOptions

type BugReportOptions struct {
	Hint           string
	IncludeSession bool
}

BugReportOptions are the user's consent choices.

type BugReportProvider

type BugReportProvider struct {
	ID                    string              `json:"id"`
	Name                  string              `json:"name"`
	BaseURL               *string             `json:"baseUrl"`
	HeaderNames           []string            `json:"headerNames"`
	AuthStatus            BugReportAuthStatus `json:"authStatus"`
	UsingOAuth            bool                `json:"usingOAuth"`
	RegisteredByExtension bool                `json:"registeredByExtension"`
}

BugReportProvider describes the current model's provider without credentials.

type BugReportSessionEntryData

type BugReportSessionEntryData struct {
	ID              string  `json:"id"`
	CreatedAt       string  `json:"createdAt"`
	Hint            *string `json:"hint"`
	SessionIncluded bool    `json:"sessionIncluded"`
	SummaryIncluded bool    `json:"summaryIncluded"`
	Delivery        string  `json:"delivery"`
	Path            string  `json:"path,omitempty"`
}

BugReportSessionEntryData is the custom entry /bug records in the session. Mirrors upstream BugReportSessionEntryData; delivery is always "zip".

type BugReportSessionInfo

type BugReportSessionInfo struct {
	ID              string `json:"id"`
	Included        bool   `json:"included"`
	SummaryIncluded bool   `json:"summaryIncluded"`
	MessageCount    int    `json:"messageCount"`
	CWD             string `json:"cwd,omitempty"`
}

BugReportSessionInfo records what the report shares about the session.

type BugReportSettings

type BugReportSettings struct {
	Global  any `json:"global"`
	Project any `json:"project"`
}

BugReportSettings holds the redacted global and project settings.

type BugReportTerminalEnv

type BugReportTerminalEnv struct {
	Term           *string `json:"term"`
	Program        *string `json:"program"`
	ProgramVersion *string `json:"programVersion"`
	Colorterm      *string `json:"colorterm"`
	Tmux           bool    `json:"tmux"`
	SSH            bool    `json:"ssh"`
	CI             bool    `json:"ci"`
}

BugReportTerminalEnv records terminal identification variables.

type BuiltinSlashCommand

type BuiltinSlashCommand struct {
	Name        string
	Aliases     []string
	Description string
	// ArgumentHint is shown after the command in autocomplete (e.g.
	// "<provider/model>"). Optional. Mirrors upstream argumentHint.
	ArgumentHint string
	Handler      SlashHandler
	// Hidden commands dispatch normally but are omitted from /help and
	// autocomplete. Mirrors upstream commands handled inline in the submit
	// handler that are absent from the canonical slash-commands.js list
	// (e.g. /debug).
	Hidden bool
}

BuiltinSlashCommand is the canonical shape for every command exposed to users. Aliases are first-class. (Note: upstream pi does NOT alias /exit → /quit; only /quit exists. We match that behavior: no alias.)

func BuiltinSlashCommands

func BuiltinSlashCommands() []BuiltinSlashCommand

BuiltinSlashCommands returns the canonical builtin slash command list (name + description + aliases). Single source of truth for `/help`, the dispatcher, and the autocomplete popup - mirrors upstream's `BUILTIN_SLASH_COMMANDS` re-export from `core/slash-commands.ts`.

type CacheWarmRequest

type CacheWarmRequest struct {
	Model   *ai.Model
	Context ai.TranscriptContext
	Options ai.StreamOptions
}

CacheWarmRequest is the request whose prompt cache entry should be kept warm, exactly as it was sent.

type CacheWarmer

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

CacheWarmer keeps one prompt cache entry alive by re-sending its request with a one-token output cap before the entry expires. Start replaces any previous run; warm requests never extend the fixed safety windows.

Upstream's unawaited setTimeout refresh maps to an owned task: a timer whose callback the warmer tracks, cancelled through the run's context and drained by Wait.

func NewCacheWarmer

func NewCacheWarmer(stream agent.StreamFn, sessionManager CacheWarmerSessionManager, getMode func() CacheWarmingMode, decide CacheWarmingDecide) *CacheWarmer

NewCacheWarmer creates a warmer. A nil decide keeps Pi's own decision.

func (*CacheWarmer) Cancel

func (w *CacheWarmer) Cancel()

Cancel stops warming. Mirrors upstream cancel().

func (*CacheWarmer) Close

func (w *CacheWarmer) Close()

Close cancels warming for good, as upstream dispose does: later Start calls are ignored and, once Close returns, no refresh reports to OnWarmed, even one still persisting its usage entry. Close waits for a report already in progress, after cancelling that report's context.

func (*CacheWarmer) OnAgentSettled

func (w *CacheWarmer) OnAgentSettled()

OnAgentSettled moves the run to its idle phase, or stops it in streaming mode.

func (*CacheWarmer) OnModeChanged

func (w *CacheWarmer) OnModeChanged()

OnModeChanged reconciles an active run after the persisted mode changes.

func (*CacheWarmer) SetOnWarmed

func (w *CacheWarmer) SetOnWarmed(onWarmed func(context.Context, UsageEntry))

SetOnWarmed sets the callback that receives the persisted usage entry after each successful refresh. Its context is cancelled when Close starts; a callback blocked on delivery must return once it is, because Close waits for it. The callback must not call Close.

func (*CacheWarmer) Start

func (w *CacheWarmer) Start(request CacheWarmRequest, isCurrent func() bool)

Start keeps the prompt cache entry written by request warm while isCurrent holds.

func (*CacheWarmer) Status

func (w *CacheWarmer) Status() CacheWarmingStatus

Status reports the current warming state and the policy inputs that produced it.

func (*CacheWarmer) Wait

func (w *CacheWarmer) Wait()

Wait blocks until every scheduled or in-flight refresh has finished, then releases the closed warmer's provider and Session references. Call it after Close.

type CacheWarmerSessionManager

type CacheWarmerSessionManager interface {
	AppendUsage(kind, provider, model string, usage ai.Usage, note string) (UsageEntry, error)
	GetBranch() []SessionEntry
}

CacheWarmerSessionManager is the Session surface the warmer uses. Mirrors Pick<SessionManager, "appendUsage" | "getBranch">.

type CacheWarmingAction

type CacheWarmingAction string

CacheWarmingAction is Pi's warm-or-stop decision.

const (
	CacheWarmingActionWarm CacheWarmingAction = "warm"
	CacheWarmingActionStop CacheWarmingAction = "stop"
)

type CacheWarmingDecide

CacheWarmingDecide lets an extension override a decision. An error falls back to Pi's decision.

type CacheWarmingDecision

type CacheWarmingDecision struct {
	// Phase is "streaming" while the agent run that sent the request is still
	// active, then "idle".
	Phase string `json:"phase"`
	// WarmCost is the price of this refresh: a cache read of the prompt plus
	// one output token.
	WarmCost float64 `json:"warmCost"`
	// MissCost is the extra price of the next real request if the entry is lost.
	MissCost float64 `json:"missCost"`
	// ContinuationProbability estimates the chance that a real request
	// arrives before the entry expires.
	ContinuationProbability float64 `json:"continuationProbability"`
	// ExpectedSavings is ContinuationProbability*MissCost - WarmCost.
	ExpectedSavings float64 `json:"expectedSavings"`
	// EconomicsAvailable is false when the prompt size or prices are unknown.
	EconomicsAvailable bool `json:"economicsAvailable"`
	// Action is "warm" when ExpectedSavings is at least $0.05.
	Action CacheWarmingAction `json:"action"`
}

CacheWarmingDecision holds the inputs and outcome of one warm-or-stop decision, as shown by /session.

type CacheWarmingDecisionEvent

type CacheWarmingDecisionEvent struct {
	Type                    string             `json:"type"`
	WarmCost                float64            `json:"warmCost"`
	MissCost                float64            `json:"missCost"`
	ContinuationProbability float64            `json:"continuationProbability"`
	Action                  CacheWarmingAction `json:"action"`
}

CacheWarmingDecisionEvent is fired before each refresh with Pi's decision filled in; an extension may override Action. Field order matches the payload upstream emits.

type CacheWarmingMode

type CacheWarmingMode string

CacheWarmingMode selects when prompt caches are kept warm. Mirrors upstream settings-manager.ts CacheWarmingMode.

type CacheWarmingStatus

type CacheWarmingStatus struct {
	// State is "inactive", "scheduled" (a refresh timer is armed), or
	// "refreshing" (a warm request is in flight).
	State string `json:"state"`
	// Reason says why nothing is scheduled.
	Reason string `json:"reason,omitempty"`
	// NextWarmAt is the Unix millisecond time of the next decision, or 0.
	NextWarmAt int64 `json:"nextWarmAt,omitempty"`
	// Decision is the pending decision, or the decision that stopped warming.
	Decision *CacheWarmingDecision `json:"decision,omitempty"`
	// ExtensionOverride is true when an extension changed Decision.Action.
	ExtensionOverride bool `json:"extensionOverride,omitempty"`
}

CacheWarmingStatus is the warmer state /session reports.

type CatalogRefreshOptions

type CatalogRefreshOptions struct {
	AllowNetwork bool
	Force        *bool
	Providers    []string
}

CatalogRefreshOptions selects providers and whether network access is allowed. An empty Providers list refreshes every dynamic provider.

type CatalogRefreshResult

type CatalogRefreshResult struct {
	Aborted bool
	Errors  map[string]error
	// contains filtered or unexported fields
}

CatalogRefreshResult mirrors upstream ModelsRefreshResult.

func RefreshModelCatalogs

func RefreshModelCatalogs(ctx context.Context, registry *ModelRegistry) (CatalogRefreshResult, error)

RefreshModelCatalogs shares concurrent interactive all-catalog refreshes for a registry while keeping each caller's cancellation independent. The last departing caller cancels the operation; a later caller can start a new refresh without waiting for abandoned work to settle.

type ChangelogEntry

type ChangelogEntry struct {
	Major   int
	Minor   int
	Patch   int
	Content string // includes the `## [x.y.z]` header line itself, trimmed
}

ChangelogEntry is one parsed `## [x.y.z]` block.

func GetNewEntries

func GetNewEntries(entries []ChangelogEntry, sinceVersion string) []ChangelogEntry

GetNewEntries returns the subset of entries whose version is strictly newer than sinceVersion (a "x.y.z" string). Mirrors upstream getNewEntries (utils/changelog.ts:84-96).

func ParseChangelog

func ParseChangelog(content string) []ChangelogEntry

ParseChangelog walks the markdown content of a CHANGELOG.md and returns one ChangelogEntry per `## [x.y.z]`-style header. Order is the order found in the file (typical convention: newest first). Malformed entries are silently skipped: matches upstream behavior (errors only logged via console.error).

type ChatViewport

type ChatViewport struct {
	Root       tui.Component
	Transcript *tui.ScrollView
}

ChatViewport is the fullscreen layout root and its transcript scroll view. Mirrors upstream ChatViewport.

func CreateChatViewport

func CreateChatViewport(options ChatViewportOptions) ChatViewport

CreateChatViewport builds the shared fullscreen transcript and fixed input-dock layout. Mirrors upstream createChatViewport.

type ChatViewportOptions

type ChatViewportOptions struct {
	Document            tui.Component
	PendingMessages     tui.Component
	Status              tui.Component
	Editor              tui.Component
	Footer              tui.Component
	WidgetsAbove        tui.Component
	WidgetsBelow        tui.Component
	Scrollbar           string
	ScrollbarTrackStyle func(text string) string
	ScrollbarThumbStyle func(text string) string
}

ChatViewportOptions mirrors upstream ChatViewportOptions (chat-viewport.ts). WidgetsAbove and WidgetsBelow are optional (nil omits the dock slot); Scrollbar "" takes upstream's "auto" default; nil styles take the ScrollView defaults.

type CodemodeMode

type CodemodeMode string

CodemodeMode is how the codemode tool presents tools while it is active. Mirrors upstream CodemodeMode (settings-manager.ts:101).

const (
	// CodemodeModeOn appends the codemode declaration to each callable tool's description and lists only tools without direct exposure in the codemode description.
	CodemodeModeOn CodemodeMode = "on"
	// CodemodeModeOnly lists every callable tool in the codemode description and does not declare active direct tools to the model.
	CodemodeModeOnly CodemodeMode = "only"
)

type CodemodeSettings

type CodemodeSettings struct {
	// Mode defaults to on.
	Mode CodemodeMode `json:"mode,omitempty"`
	// InlineBudget is the estimated tokens (characters / 4) the codemode description may spend on tool declarations. Default 3000.
	InlineBudget *int `json:"inlineBudget,omitempty"`
}

CodemodeSettings mirrors upstream CodemodeSettings (settings-manager.ts:103).

type CompactionConfig

type CompactionConfig struct {
	Enabled          bool
	ReserveTokens    int
	KeepRecentTokens int
}

CompactionConfig mirrors compaction.CompactionSettings but lives here to avoid an import cycle (compaction imports codingagent for SessionEntry).

type CompactionEntry

type CompactionEntry struct {
	SessionEntryBase
	Summary          string    `json:"summary"`
	FirstKeptEntryID string    `json:"firstKeptEntryId"`
	TokensBefore     int       `json:"tokensBefore"`
	Details          any       `json:"details,omitempty"`
	Usage            *ai.Usage `json:"usage,omitempty"`
	FromHook         bool      `json:"fromHook"`
	// SystemMessage is the complete prompt and tool state at this compaction
	// boundary. It is absent when the projected context has no system state.
	SystemMessage json.RawMessage `json:"systemMessage,omitempty"`
}

CompactionEntry field order matches Pi's appendCompaction object literal so Pig-written entries serialize with the same key order.

type CompactionModelOverride

type CompactionModelOverride struct {
	ReserveTokens    *float64 `json:"reserveTokens,omitempty"`
	KeepRecentTokens *float64 `json:"keepRecentTokens,omitempty"`
	// contains filtered or unexported fields
}

CompactionModelOverride mirrors upstream CompactionModelOverride. Pointers keep an explicit zero, as upstream's `override ?? ordinary` does.

func (CompactionModelOverride) MarshalJSON

func (s CompactionModelOverride) MarshalJSON() ([]byte, error)

func (*CompactionModelOverride) UnmarshalJSON

func (s *CompactionModelOverride) UnmarshalJSON(data []byte) error

type CompactionSettingsJSON

type CompactionSettingsJSON struct {
	Enabled *bool `json:"enabled,omitempty"`
	// ReserveTokens and KeepRecentTokens retain JavaScript numbers until getter validation, including zero, fractions, and non-finite runtime overrides.
	ReserveTokens    *float64 `json:"reserveTokens,omitempty"`
	KeepRecentTokens *float64 `json:"keepRecentTokens,omitempty"`
	// ModelOverrides maps exact "provider/modelId" keys to token settings
	// that take precedence for that model.
	ModelOverrides map[string]CompactionModelOverride `json:"modelOverrides,omitempty"`
	// contains filtered or unexported fields
}

CompactionSettingsJSON mirrors upstream Settings.compaction JSON shape (settings-manager.ts:74). Pointer to *bool for enabled to distinguish absent vs. explicitly-false.

func (CompactionSettingsJSON) MarshalJSON

func (s CompactionSettingsJSON) MarshalJSON() ([]byte, error)

func (*CompactionSettingsJSON) UnmarshalJSON

func (s *CompactionSettingsJSON) UnmarshalJSON(data []byte) error

type ContextEditEntry

type ContextEditEntry struct {
	SessionEntryBase
	TargetID    string                  `json:"targetId"`
	Replacement *ContextEditReplacement `json:"replacement"`
}

ContextEditEntry is an append-only change to one earlier entry's contribution to model context (session-manager.ts ContextEditEntry). A nil Replacement serializes as null and omits the target from model context; a replacement changes only the target's content. The target entry itself is never rewritten.

type ContextEditReplacement

type ContextEditReplacement struct {
	Content json.RawMessage `json:"content"`
}

ContextEditReplacement is the non-null replacement of a context_edit entry (session-manager.ts ContextEditEntry.replacement). Content is the JSON string or content-block array that replaces the target's content (ContextEditableContent).

type ContextFile

type ContextFile struct {
	Path    string
	Content string
}

ContextFile holds a loaded project context file (AGENTS.override.md, AGENTS.md, or CLAUDE.md). Mirrors upstream resource-loader.ts::loadProjectContextFiles return shape.

func LoadProjectContextFiles

func LoadProjectContextFiles(cwd, agentDir string) []ContextFile

LoadProjectContextFiles discovers and loads project context files from the agent config directory and every ancestor directory from cwd up to the filesystem root.

Load order (matches upstream resource-loader.ts:76-115):

  1. Agent config dir (e.g. ~/.pig/): global context
  2. Ancestor directories from root down to cwd: project context

Within each directory, AGENTS.override.md replaces that directory's regular AGENTS/CLAUDE candidate while ancestor layering remains intact. Duplicate paths are skipped by their loaded path. In a nested linked worktree, the main checkout's same-named context file is skipped when the worktree root supplies its own copy. Nonempty input paths resolve against the process working directory before discovery.

type CrashInput

type CrashInput struct {
	Kind        string
	Message     string
	Stack       string
	SessionFile string
	CWD         string
	Version     string
}

CrashInput describes a crash to record.

type CrashRecord

type CrashRecord struct {
	Timestamp   string  `json:"timestamp"`
	Version     string  `json:"version"`
	Kind        string  `json:"kind"`
	Message     string  `json:"message"`
	Stack       *string `json:"stack"`
	SessionFile *string `json:"sessionFile"`
	CWD         string  `json:"cwd"`
	Notified    bool    `json:"notified,omitempty"`
}

CrashRecord is one crashes.json entry. Mirrors upstream CrashRecord; Kind is "uncaught_exception" or "fatal_error".

func ReadCrashLog

func ReadCrashLog(path string) []CrashRecord

ReadCrashLog returns the valid records, or none when the file is missing or unreadable. A record needs a string timestamp and message. Mirrors upstream readCrashLog.

func RecordCrash

func RecordCrash(crash CrashInput, path string, now time.Time) (CrashRecord, bool)

RecordCrash appends a crash, keeping the newest five. It is best effort for callers that are already crashing: it reports ok=false when nothing was written. Mirrors upstream recordCrash.

func TakeUnnotifiedCrash

func TakeUnnotifiedCrash(path string, now time.Time) (CrashRecord, bool)

TakeUnnotifiedCrash returns the newest crash from the last seven days that has not been announced, and marks every record announced. Mirrors upstream takeUnnotifiedCrash.

type CredentialSynchronizationError

type CredentialSynchronizationError struct {
	ProviderID string
	Operation  CredentialSynchronizationOperation
	Credential *ai.Credential
	Cause      error
}

CredentialSynchronizationError reports a committed credential change whose local model/auth snapshot could not be synchronized.

func (*CredentialSynchronizationError) Error

func (*CredentialSynchronizationError) Unwrap

type CredentialSynchronizationOperation

type CredentialSynchronizationOperation string

CredentialSynchronizationOperation identifies the credential change that committed before synchronization failed.

const (
	CredentialSynchronizationLogin               CredentialSynchronizationOperation = "login"
	CredentialSynchronizationLogout              CredentialSynchronizationOperation = "logout"
	CredentialSynchronizationSetRuntimeAPIKey    CredentialSynchronizationOperation = "setRuntimeApiKey"
	CredentialSynchronizationRemoveRuntimeAPIKey CredentialSynchronizationOperation = "removeRuntimeApiKey"
)

type CustomEntry

type CustomEntry struct {
	SessionEntryBase
	CustomType string `json:"customType"`
	Data       any    `json:"data,omitempty"`
}

func AppendExtensionEntry

func AppendExtensionEntry(sess *Session, customType string, data any, direct *subprocess.DirectEntryAppend) (CustomEntry, error)

AppendExtensionEntry validates or allocates the identity and appends under one Session mutation lock. A rejected direct identity cannot overwrite an existing entry.

func (*CustomEntry) UnmarshalJSON

func (e *CustomEntry) UnmarshalJSON(data []byte) error

UnmarshalJSON keeps the member order of `data`, the object an extension wrote (session-manager.ts appendCustomEntry).

type CustomMessageEntry

type CustomMessageEntry struct {
	SessionEntryBase
	CustomType string `json:"customType"`
	Content    any    `json:"content"` // string | []ContentBlock
	Display    bool   `json:"display"`
	Details    any    `json:"details,omitempty"`
}

func (*CustomMessageEntry) UnmarshalJSON

func (e *CustomMessageEntry) UnmarshalJSON(data []byte) error

UnmarshalJSON keeps the member order of `details`, the object an extension wrote (session-manager.ts appendCustomMessageEntry).

type ExtUIContext

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

ExtUIContext implements extension.UIContext for interactive mode. Subprocess extensions' Select/Confirm/Input/Editor calls are dispatched here via the UIBridge.

func (*ExtUIContext) AddAutocompleteProvider

func (u *ExtUIContext) AddAutocompleteProvider(factory extension.AutocompleteProviderFactory) error

func (*ExtUIContext) AddAutocompleteProviderWithLifetime

func (u *ExtUIContext) AddAutocompleteProviderWithLifetime(lifetime context.Context, factory extension.AutocompleteProviderFactory) error

AddAutocompleteProviderWithLifetime drops registrations when their owning extension connection ends.

func (*ExtUIContext) AutocompleteProvider

func (u *ExtUIContext) AutocompleteProvider(ctx context.Context) (*extension.AutocompleteProvider, error)

AutocompleteProvider captures the active chain for a subprocess editor. Both editors use that same provider instance.

func (*ExtUIContext) Confirm

func (u *ExtUIContext) Confirm(ctx context.Context, title, message string, opts extension.ExtensionUIDialogOptions) (bool, error)

Confirm shows a Yes/No selector. Mirrors upstream's showExtensionConfirm (interactive-mode.ts:1996-2003).

func (*ExtUIContext) Custom

func (u *ExtUIContext) Custom(ctx context.Context, factory any, opts any) (any, error)

Custom runs an in-process factory and shows its component in the editor slot, or over the screen, until the factory's done callback ends the call with a result. upstream: packages/coding-agent/src/modes/interactive/interactive-mode.ts:2863-2935 (showExtensionCustom)

func (*ExtUIContext) Editor

func (u *ExtUIContext) Editor(ctx context.Context, title, prefill string) (string, error)

Editor shows a multi-line editor in the editor slot. Mirrors upstream's showExtensionEditor in interactive-mode.ts, which creates an ExtensionEditorComponent and swaps it into the editorContainer.

func (*ExtUIContext) GetAllThemes

func (u *ExtUIContext) GetAllThemes() []extension.ThemeMeta

GetAllThemes lists the themes the user can switch to, mirroring upstream's getAllThemes (getAvailableThemesWithPaths). Path is empty for built-in themes, matching upstream's `path: string | undefined`.

func (*ExtUIContext) GetEditorComponent

func (u *ExtUIContext) GetEditorComponent() any

func (*ExtUIContext) GetEditorText

func (u *ExtUIContext) GetEditorText() string

GetEditorText reads owner-published expanded text after binding, including paste contents. Before binding the caller owns the editor directly.

func (*ExtUIContext) GetTheme

func (u *ExtUIContext) GetTheme(name string) (extension.Theme, error)

GetTheme loads a theme's portable palette without selecting it. Missing names return absence, as Pi's getThemeByName does. The theme is in the terminal's color mode, as Pi's createTheme defaults it (theme.ts:599-600).

func (*ExtUIContext) GetToolsExpanded

func (u *ExtUIContext) GetToolsExpanded() bool

func (*ExtUIContext) Input

func (u *ExtUIContext) Input(ctx context.Context, title, placeholder string, opts extension.ExtensionUIDialogOptions) (string, error)

Input shows a text input in the editor slot. Blocks until the user submits (Enter) or cancels (Esc). Mirrors upstream's showExtensionInput in interactive-mode.ts. A positive opts timeout counts down in the title and cancels the input when it expires.

func (*ExtUIContext) Notify

func (u *ExtUIContext) Notify(message, kind string)

func (*ExtUIContext) OnRemoteTerminalInput

func (u *ExtUIContext) OnRemoteTerminalInput(extensionName string, handler extension.RemoteTerminalInputHandler) func()

OnRemoteTerminalInput registers a subprocess extension's listener. The input loop asks it off the loop and applies its verdict in input order.

func (*ExtUIContext) OnTerminalInput

func (u *ExtUIContext) OnTerminalInput(handler extension.TerminalInputHandler) func()

func (*ExtUIContext) PasteToEditor

func (u *ExtUIContext) PasteToEditor(text string)

func (*ExtUIContext) RegisterSprite

func (u *ExtUIContext) RegisterSprite(owner string, definition extension.ValidatedSpriteDefinition) error

RegisterSprite adds an extension's sprite to /sprite (D2). The header redraws, since it may be the saved sprite, drawn as the default until now.

func (*ExtUIContext) ReportsDialogInitiation

func (u *ExtUIContext) ReportsDialogInitiation() bool

ReportsDialogInitiation reports that Select, Confirm, Input, and Editor mark their call initiated once the dialog is queued for installation.

func (*ExtUIContext) RunRemoteOverlay

func (u *ExtUIContext) RunRemoteOverlay(opts extension.RemoteOverlayOptions, host extension.RemoteOverlayHost, onHandle func(extension.RemoteOverlayHandle)) (any, bool)

RunRemoteOverlay mounts remote custom UI as an overlay or editor-slot replacement and waits for its result. The owner loop mounts the component and transfers renderer focus; this caller drains its modal input lease off-loop. Normal completion restores the editor slot and focus before returning.

func (*ExtUIContext) Select

func (u *ExtUIContext) Select(ctx context.Context, title string, options []string, opts extension.ExtensionUIDialogOptions) (string, error)

Select shows a generic option list in the editor slot. Blocks until the user picks an option or cancels (Esc). Mirrors upstream's showExtensionSelector in interactive-mode.ts using the standalone ExtensionSelectorComponent (NO filter input, fixed title row, fixed hint row). A positive opts timeout counts down in the title and cancels the selector when it expires.

func (*ExtUIContext) SetEditorComponent

func (u *ExtUIContext) SetEditorComponent(factory any)

SetEditorComponent installs an extension's editor component in place of the editor, or with nil restores the editor, as Pi's setEditorComponent does (remote_editor.go).

func (*ExtUIContext) SetEditorText

func (u *ExtUIContext) SetEditorText(text string)

func (*ExtUIContext) SetFooter

func (u *ExtUIContext) SetFooter(factory any)

func (*ExtUIContext) SetHeader

func (u *ExtUIContext) SetHeader(factory any)

func (*ExtUIContext) SetHiddenThinkingLabel

func (u *ExtUIContext) SetHiddenThinkingLabel(label string)

func (*ExtUIContext) SetLogin

func (u *ExtUIContext) SetLogin(definition extension.LoginDefinition) error

func (*ExtUIContext) SetStatus

func (u *ExtUIContext) SetStatus(key, text string)

SetStatus forwards a keyed status to the footer and requests a render, like upstream setExtensionStatus. Extensions call it from their own timers, so the render request is what paints it while the session is idle.

func (*ExtUIContext) SetTheme

func (u *ExtUIContext) SetTheme(theme any) extension.SetThemeResult

SetTheme disables automatic switching, applies a named theme, and persists a successful choice. An unknown name falls back to the system theme and returns failure without changing the stored selection (theme.ts setTheme).

func (*ExtUIContext) SetTitle

func (u *ExtUIContext) SetTitle(title string)

func (*ExtUIContext) SetToolsExpanded

func (u *ExtUIContext) SetToolsExpanded(expanded bool)

func (*ExtUIContext) SetWidget

func (u *ExtUIContext) SetWidget(key string, content any, opts extension.ExtensionWidgetOptions)

func (*ExtUIContext) SetWorkingIndicator

func (u *ExtUIContext) SetWorkingIndicator(options extension.WorkingIndicatorOptions)

func (*ExtUIContext) SetWorkingMessage

func (u *ExtUIContext) SetWorkingMessage(message string)

func (*ExtUIContext) SetWorkingVisible

func (u *ExtUIContext) SetWorkingVisible(visible bool)

func (*ExtUIContext) Theme

func (u *ExtUIContext) Theme() extension.Theme

func (*ExtUIContext) UnregisterSprites

func (u *ExtUIContext) UnregisterSprites(owner string)

UnregisterSprites removes the sprites of an extension that unloaded; the header redraws in case it showed one.

type ExtensionCommandLister

type ExtensionCommandLister interface {
	Commands() []extension.ResolvedCommand
}

ExtensionCommandLister is the extension runner surface the command catalog reads.

type ExtensionConflict

type ExtensionConflict struct {
	Path    string
	Message string
}

ExtensionConflict is a tool or flag that an extension registers after another extension, at a different path, already registered it.

func DetectExtensionConflicts

func DetectExtensionConflicts(exts []extension.Extension) []ExtensionConflict

DetectExtensionConflicts mirrors upstream resource-loader.ts detectExtensionConflicts. It walks extensions in load order and each extension's tools in registration order, keeps the first owner of each tool and flag name, and reports every later registration by another extension. All extensions stay loaded; upstream adds the conflicts to the extension load errors. Flags have no recorded registration order and are walked by name.

type ExtensionContext

type ExtensionContext struct {
	UI      ExtensionUIContext
	HasUI   bool
	CWD     string
	Session *Session
	Model   *ai.Model
	IsIdle  func() bool
	// IsProjectTrusted mirrors upstream ExtensionContext.isProjectTrusted
	// (types.ts:332). Trust can be granted mid-session, so it is a function
	// rather than a snapshot.
	IsProjectTrusted func() bool
	AbortSignal      context.Context
	AbortFunc        context.CancelFunc
}

ExtensionContext is shared mutable state for the agent loop. Passed to slash command handlers and event bridges.

type ExtensionOAuthConfig

type ExtensionOAuthConfig struct {
	Name           string
	IsSubscription bool
	Login          func(context.Context, ai.OAuthLoginCallbacks) (ai.Credential, error)
	RefreshToken   func(context.Context, ai.Credential) (ai.Credential, error)
	GetAPIKey      func(ai.Credential) string
	ModifyModels   func([]*ai.Model, ai.Credential) []*ai.Model
}

ExtensionOAuthConfig adapts the legacy provider-registration callbacks to native provider auth.

type ExtensionSessionView

type ExtensionSessionView struct {
	Session    *Session
	CWD        string
	SessionDir string
}

ExtensionSessionView names the session an extension reads and the facts the session file does not hold: the session manager's cwd, its session directory, and whether it persists (upstream SessionManager cwd, sessionDir and persist).

type ExtensionStackMetadata

type ExtensionStackMetadata struct {
	Path         string
	ResolvedPath string
	SourceInfo   ResourceSourceInfo
}

ExtensionStackMetadata is the loaded extension provenance used to attribute stack frames after a crash.

type ExtensionToolLister

type ExtensionToolLister interface {
	Tools() []extension.RegisteredTool
	ToolSourceInfo(toolName string) (extension.SourceInfo, bool)
}

ExtensionToolLister is the extension runner surface ExtensionToolInfos reads.

type ExtensionUIContext

type ExtensionUIContext interface {
	Select(title string, options []string) (string, bool)
	Confirm(title, message string) bool
	Input(title, placeholder string) (string, bool)
	Notify(message, level string)
	SetStatus(key, text string)
	SetWidget(key string, lines []string)
}

ExtensionUIContext mirrors the upstream ExtensionUIContext interface. In interactive mode this is backed by the TUI; in headless/print mode it falls back to no-op implementations.

type FetchUpdateManifestOptions

type FetchUpdateManifestOptions struct {
	Retry bool
}

FetchUpdateManifestOptions selects explicit-update transport retries. Startup checks leave Retry false.

type FindInitialModelOptions

type FindInitialModelOptions struct {
	CLIProvider          string
	CLIModel             string
	ScopedModels         []ScopedModel
	IsContinuing         bool
	DefaultProvider      string
	DefaultModelId       string
	DefaultThinkingLevel string
	ModelThinkingLevels  map[string]string
	ModelRuntime         InitialModelRuntime
}

FindInitialModelOptions carries selection inputs without owning a Model Runtime, refreshing its snapshots, or resolving credentials. Empty optional thinking strings represent no selection.

type FirstTimeSetupComponent

type FirstTimeSetupComponent struct {
	*tui.Container
	// contains filtered or unexported fields
}

FirstTimeSetupComponent is the first-time setup dialog: theme, sprite and analytics opt-in. pig divergence (D88): the dialog's logo is the pig head of the sprite in view, not Pi's SETUP_LOGO_LINES, and a sprite step follows the theme step; its options are the built-in sprites, then the extension-registered ones (piglogin.All).

func NewFirstTimeSetupComponent

func NewFirstTimeSetupComponent(options FirstTimeSetupOptions) *FirstTimeSetupComponent

NewFirstTimeSetupComponent builds the dialog over the sprites offered at construction, starting on the active sprite.

func (*FirstTimeSetupComponent) Done

func (c *FirstTimeSetupComponent) Done() bool

Done reports whether the dialog was submitted or skipped.

func (*FirstTimeSetupComponent) HandleInput

func (c *FirstTimeSetupComponent) HandleInput(data string)

HandleInput moves, advances, submits or cancels.

func (*FirstTimeSetupComponent) Invalidate

func (c *FirstTimeSetupComponent) Invalidate()

Invalidate rebuilds on theme changes, e.g. when the system theme receives the terminal's colors.

type FirstTimeSetupOptions

type FirstTimeSetupOptions struct {
	OnThemePreview func(themeName string)
	OnSubmit       func(result FirstTimeSetupResult)
	OnCancel       func()
}

FirstTimeSetupOptions are the dialog's callbacks.

type FirstTimeSetupResult

type FirstTimeSetupResult struct {
	Theme          string
	Sprite         string
	ShareAnalytics bool
}

FirstTimeSetupResult is the dialog's submitted choice.

func ShowFirstTimeSetup

func ShowFirstTimeSetup(settings FirstTimeSetupSettings, opts StartupUIOptions) (*FirstTimeSetupResult, error)

ShowFirstTimeSetup shows the first-time setup dialog on its own screen before the interactive TUI starts, as Pi's showFirstTimeSetup does (cli/startup-ui.ts:182-218, main.ts:672-676), and persists a submitted result: the theme and analytics opt-in in settings, and the sprite exactly as /sprite set saves it. It returns the submitted result, or nil when setup was skipped. pig divergence (D88): the sprite step offers the built-in sprites; extensions are not loaded yet, so their sprites are chosen later with /sprite.

type FirstTimeSetupSettings

type FirstTimeSetupSettings interface {
	SetTheme(name string) error
	SetEnableAnalytics(enabled bool) error
}

FirstTimeSetupSettings is the settings store a submitted first-time setup writes.

type InitialModelResult

type InitialModelResult struct {
	Model           *RuntimeModel
	ThinkingLevel   string
	FallbackMessage string
}

InitialModelResult preserves selection-dependent thinking. Provider-default, first-available, and no-model fallbacks use DefaultThinkingLevel, not the caller's saved level.

func FindInitialModel

func FindInitialModel(options FindInitialModelOptions) (InitialModelResult, error)

FindInitialModel selects explicit CLI, new-session scope, authenticated saved default, or an available fallback in that order. CLI resolution errors are returned for the caller to display and terminate; this library does not log or exit.

type InitialModelRuntime

type InitialModelRuntime interface {
	ModelResolverRuntime
	GetModel(providerID, modelID string) *RuntimeModel
	GetAvailableSnapshot() []RuntimeModel
}

InitialModelRuntime keeps exact catalog lookup and the available snapshot separate. A configured provider may have models that are absent from the available snapshot.

type InteractiveForkResult

type InteractiveForkResult struct {
	Cancelled    bool
	SelectedText *string
}

InteractiveForkResult is the outcome of a runtime fork. SelectedText is absent when the fork is at an entry, and for a cancelled fork.

type InteractiveMode

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

InteractiveMode runs the full interactive TUI session.

func NewInteractiveMode

func NewInteractiveMode(opts InteractiveOptions) *InteractiveMode

NewInteractiveMode creates an interactive session.

func (*InteractiveMode) Run

func (m *InteractiveMode) Run(ctx context.Context) (err error)

Run renders the initial editor and footer even with quiet startup, then blocks in the interactive loop until the user exits.

func (*InteractiveMode) ShutdownFromSignal

func (m *InteractiveMode) ShutdownFromSignal()

ShutdownFromSignal emits session_shutdown before requesting owner-loop teardown. Concurrent callers join ongoing cleanup, and repeated calls do not emit again.

Upstream's signal-triggered shutdown emits extension cleanup BEFORE touching the terminal, because teardown such as removing sockets does not write to the tty and must not be skipped if a later terminal-restore write fails (interactive-mode.ts shutdown({fromSignal: true})).

Ordering matters in pig for a second reason: extension subprocesses are spawned with the root context, so cancelling it kills them. If SIGTERM cancelled the context first, the shutdown event would be delivered to processes that no longer exist and extensions would silently never clean up. The caller therefore invokes this before cancelling.

type InteractiveOptions

type InteractiveOptions struct {
	CWD      string
	AgentDir string
	Model    *ai.Model
	Settings Settings
	// InitialThemeSetting selects a theme for this run without changing the SettingsManager. A non-nil empty name is a selection that fails and falls back to dark. Explicit selections replace it; absent selections follow the current manager.
	InitialThemeSetting *string
	// TuiMode selects "regular" or "fullscreen" for this run without changing the SettingsManager. Empty captures Settings.TuiMode at construction; only a live mode switch changes it afterwards.
	TuiMode string
	// SettingsManager provides read/write access to global settings.
	// Wired by main.go via coding.Services.
	SettingsManager *SettingsManager
	// SystemPrompt overrides the assembled system prompt. If empty,
	// callers should build one via prompts.BuildDefaultPrompt and pass
	// it in.
	SystemPrompt string
	// SystemPromptOptions mirrors upstream
	// `BuildSystemPromptOptions` (system-prompt.ts:8-25). It carries
	// the structured inputs that produced SystemPrompt (custom prompt,
	// tools, append text, context files, skills) and is passed verbatim
	// to extensions on every before_agent_start event so they can
	// inspect what pi has loaded without re-discovering resources.
	//
	// upstream: agent-session.ts:_rebuildSystemPrompt
	SystemPromptOptions extension.BuildSystemPromptOptions
	// AllowedTools restricts which tool names may execute. nil means no
	// restriction; a non-nil empty map blocks every tool. Mirrors the
	// `tools:` allowlist on agent .md frontmatter.
	AllowedTools map[string]struct{}
	// ActiveBuiltinTools, when non-nil, restricts which built-in coding
	// tools are active (caller/extension tools unaffected). nil = all
	// built-in tools. Mirrors upstream defaultActiveToolNames (sdk.ts:244):
	// CLI default [read, bash, edit, write]; grep/find/ls inactive unless
	// requested via --tools.
	ActiveBuiltinTools map[string]struct{}
	// ExcludedTools is a denylist of tool names made non-callable, gating
	// built-in and extension tools alike. Mirrors upstream excludedToolNames
	// (sdk.ts:246) + isAllowedTool (agent-session.ts:2288).
	ExcludedTools map[string]struct{}
	// ToolRegistryAllowed is the --tools allowlist bounding the tool registry
	// pi.getAllTools() reports (upstream _allowedToolNames): nil admits every
	// tool, an empty map none. Unlike AllowedTools, active-tool changes never
	// modify it.
	ToolRegistryAllowed map[string]struct{}
	// NoBuiltinTools hides built-in tools while leaving extension/custom tools.
	NoBuiltinTools bool
	// PromptPaths lists additional prompt-template directories.
	// Mirrors upstream `additionalPromptTemplatePaths`.
	// Directories are searched after the default <agentDir>/prompts/ and
	// <cwd>/.pig/prompts/ (last-wins by name, same as project scope).
	PromptPaths []string
	// SessionDir overrides the on-disk session directory used by /new,
	// /resume, and other interactive session-management flows.
	SessionDir string
	// SessionID specifies an exact session ID for new sessions.
	// Mirrors upstream --session-id (v0.76.0). When non-empty and no
	// existing session matches, Create uses this ID instead of
	// generating a random one.
	SessionID string
	// ThemePaths lists resolved theme files/directories in resource precedence order.
	ThemePaths []string
	// NoPromptTemplates disables prompt template discovery.
	NoPromptTemplates bool
	// NoThemes disables custom theme discovery from disk.
	NoThemes bool

	// UnknownFlags carries CLI flags not claimed by the core parser so
	// extensions can resolve their registered values at runtime.
	UnknownFlags map[string]any
	// BeforeToolCall hooks run at agent-loop time and can block tool
	// execution. The allowlist hook provides defense in depth alongside
	// the registration-time filter.
	BeforeToolCall []agent.BeforeToolCallHook

	// SessionHandle, when non-nil, is the pre-constructed agent +
	// on-disk session that InteractiveMode wraps for the TUI.
	// Constructed by the caller via coding.NewSession from the public
	// SDK package; main.go does the bridging between coding.* and
	// internal/codingagent.*. When nil, Run() returns an error: the
	// SDK is the only supported construction path post-Chunk F.
	//
	// Mutually exclusive with ResumePath: if SessionHandle is set,
	// the caller is responsible for having loaded the session via
	// coding.NewSession's ResumePath field.
	SessionHandle InteractiveSessionHandle

	// ContextUsage returns the live Session projection estimate for stock footer and extension usage reads.
	ContextUsage func() (tokens *int, contextWindow int)

	// ModelBuilder constructs an *ai.Model from a "<provider>/<id>"
	// spec. Wired by main.go to coding.BuildModel: the public SDK
	// can't be imported from internal/codingagent (cycle), so the
	// caller injects the constructor. nil disables /model switching
	// (handler falls back to print-only).
	ModelBuilder func(spec string) (*ai.Model, error)

	// DefaultModelPerProvider shares the startup resolver's provider defaults with /login.
	DefaultModelPerProvider map[string]string

	// ModelLookup resolves a provider/model identity through the Session-owned runtime.
	ModelLookup  func(providerID, modelID string) *ai.Model
	ModelCatalog func() []*ai.Model
	// ModelClassify is the Session-owned runtime classify an extension's ctx.modelRegistry.classify reaches.
	ModelClassify func(context.Context, *ai.ClassifierModel, ai.ClassifierContext, ...ai.ModelsClassifierOptions) ai.ClassifierResult
	// ModelGenerateImages is the Session-owned runtime generateImages an extension's ctx.modelRegistry.generateImages reaches.
	ModelGenerateImages func(context.Context, *ai.ImageModel, ai.ImagesContext, ...ai.ModelsImagesOptions) ai.AssistantImages

	// RequestAuthRuntime is the composed checkAuth/getAuth surface used by
	// warning-only auth checks. Wired by main.go from the same credential and
	// provider configuration used for model requests.
	RequestAuthRuntime *RequestAuthRuntime

	// ModelRegistry is the model registry for auth-aware operations
	// (Refresh, GetAvailable, HasConfiguredAuth). Wired by main.go.
	// nil is safe; post-login refresh is skipped.
	// Mirrors upstream session.modelRegistry (interactive-mode.ts:4394).
	ModelRegistry *ModelRegistry

	// ExtensionRunner is the new-style (`coding/extension`) runner.
	// May be nil during tests or when no extensions are loaded.
	// Events are dispatched through this runner via event_bridge.go.
	ExtensionRunner *inproc.Runner

	// SessionStartEvent is the factory-selected startup/new/resume/fork event for the current Session.
	SessionStartEvent *extension.SessionStartEvent

	// ExtensionContext is the live extension context shared with the
	// runner. Caller-supplied to ensure extCtx.Session points at the
	// SAME on-disk session SessionHandle wraps.
	ExtensionContext *ExtensionContext

	// ResumePath, when non-empty, is loaded as the active session at
	// startup. The agent's message history is rebuilt from
	// session.BuildContext() and the transcript is replayed inline so
	// the user sees prior conversation.
	ResumePath string
	// InitialMessage, when non-empty, is auto-submitted to the agent
	// immediately after the TUI initialises. Mirrors upstream's
	// `initialMessage` plumbing at
	// `.upstream/current/packages/coding-agent/src/cli/initial-message.ts`.
	// Sourced by main.go from positional args + piped stdin so users
	// can `pig "hello"`, `pig < file.txt`, or pipe + run.
	InitialMessage string
	InitialImages  []ai.ImageContent
	// InitialMessages are the positional messages after the first. Each is
	// sent as its own prompt once the previous one settles (upstream
	// initialMessages).
	InitialMessages []string

	// AppVersion is the binary version string used to detect
	// changelog-seen state. Set to UpstreamVersion (the port target).
	// gate the startup "what's new" changelog notification.
	// Mirrors upstream this.version in InteractiveMode constructor.
	AppVersion string

	// PackageUpdateChecker, if set, is invoked asynchronously at startup
	// to check for available package updates. The returned strings are
	// the display names of packages with available updates. When the
	// returned slice is non-empty, an "X package updates available"
	// banner is shown. Mirrors upstream checkForPackageUpdates +
	// showPackageUpdateNotification (interactive-mode.ts:660-665, 3449).
	PackageUpdateChecker func() []string

	// BinaryUpdateChecker, if set, is invoked asynchronously at startup and
	// returns a newer-release notice for the pig binary itself, or nil. pig
	// divergence (D39): standalone-binary self-update. The notice names the
	// command that applies it (e.g. `pig update self`).
	BinaryUpdateChecker func() *BinaryUpdate

	// Llama is Pi's built-in llama.cpp provider: /llama manages its router
	// models, /login configures it, and startup refreshes its catalog.
	Llama *llama.Host
	// OfflineMode skips startup network catalog refreshes, like PI_OFFLINE.
	OfflineMode bool

	// ResourceSourceInfoProvider returns source metadata for currently known
	// prompts/skills/extensions/themes, keyed by absolute path. Used to enrich
	// verbose startup output and /reload diagnostics with package origin.
	// Mirrors upstream resource-loader.ts PathMetadata/SourceInfo plumbing.
	ResourceSourceInfoProvider func() map[string]ResourceSourceInfo
	// ReloadResourceProvider recomputes settings-backed prompt/theme/skill/
	// context-file inputs on /reload so the interactive session mirrors
	// upstream resourceLoader.reload() instead of reusing startup snapshots.
	ReloadResourceProvider func() ReloadResourceSnapshot

	// Verbose forces verbose startup output (overrides quietStartup).
	// Mirrors upstream InteractiveOptions.verbose (interactive-mode.ts:184).
	Verbose bool

	// Skills is the loaded set of skill definitions, used to expand
	// /skill:name commands in user prompts.
	// Mirrors upstream resourceLoader.getSkills() (agent-session.ts:1124-1151).
	Skills []*SkillDef
	// SkillDiagnostics retains ordered load-time collisions for the startup listing.
	SkillDiagnostics []extension.ResourceDiagnostic
	// RebuildSystemPrompt reconstructs the base system prompt + structured
	// prompt options after /reload from the current skills/context files.
	// Mirrors upstream session.reload() → _rebuildSystemPrompt.
	RebuildSystemPrompt func(skills []*SkillDef, contextFiles []ContextFile) (string, extension.BuildSystemPromptOptions)
	// BridgeExtensionTools converts registered extension tools into
	// agent.AgentTool values so /reload can refresh the live tool registry.
	BridgeExtensionTools func([]extension.RegisteredTool) ([]agent.AgentTool, []error)
	// SkillPaths are the source paths from which Skills were loaded.
	// Used by /reload to re-discover skills from disk. If empty, skills
	// are not reloaded (only the initial set from startup is used).
	SkillPaths []string
	// NoSkills disables automatic skill discovery; explicitly selected and extension-discovered paths still load on reload.
	NoSkills bool

	// ContextFiles lists the loaded AGENTS.md/CLAUDE.md project context files.
	// The loaded-resources [Context] section lists them after
	// SystemPromptSourcePaths.
	ContextFiles []ContextFile

	// SystemPromptSourcePaths are the existing files the system prompt and
	// then each appended system prompt were read from, as upstream
	// getSystemPromptSource and getAppendSystemPromptSources report them.
	SystemPromptSourcePaths []string

	// Runtime, when set, owns Session replacement: new, resume, fork, clone and import build the destination Session through its factory. ReplacementResources then supplies the destination build's options.
	Runtime InteractiveRuntime
	// ReplacementResources returns the cwd-bound options of the build that owns session.
	ReplacementResources func(session InteractiveSessionHandle) InteractiveReplacement

	// SubprocessUIBridge, when non-nil, is the UI bridge for subprocess
	// extensions. Run() wires it to the TUI after creation via
	// SetUIContext and SetInvalidate.
	//
	// pig-specific: no upstream equivalent.
	SubprocessUIBridge SubprocessUIBridge

	// SubprocessHost, when non-nil, manages subprocess extension lifecycle.
	// Used by /reload to rebuild and re-spawn changed extensions.
	//
	// pig-specific: no upstream equivalent.
	SubprocessHost SubprocessHost

	// TerminateExtensionProcesses, when set, kills every extension process without running extension callbacks. It runs before an emergency exit on a dead terminal, which skips orderly shutdown.
	TerminateExtensionProcesses func()

	// StageExtensionSDKs, when non-nil, materializes the SDKs this binary
	// embeds before /reload recompiles out-of-tree extensions, and prunes
	// builds whose fingerprint proves they came from an older SDK.
	//
	// Injected so this package does not depend on the SDK bundle implementation
	// and so a test can observe that reload stages before it rebuilds.
	//
	// pig-specific: no upstream equivalent, because upstream extensions are
	// in-process TypeScript and there is no SDK to stage.
	StageExtensionSDKs func() error

	// BuiltinExtensions contains generic in-process runtime extensions, such as
	// Piglet capability scoping, in configured load order after subprocess
	// extensions.
	BuiltinExtensions []extension.Extension

	// ReloadBuiltinExtensions reconstructs BuiltinExtensions for /reload. A
	// factory callback is required because copying an Extension would retain the
	// handler closures and state that upstream discards on reload.
	ReloadBuiltinExtensions func() []extension.Extension

	// NoModelWarning carries the interactive-only model-selection diagnostic, including a failed saved-model restoration followed by a fallback.
	NoModelWarning string
	// StartupDiagnostics are shown in the chat after the welcome banner.
	// Mirrors upstream InteractiveModeOptions.startupDiagnostics.
	StartupDiagnostics []AgentSessionRuntimeDiagnostic

	// StartupMark, when non-nil, is called at key phases during Run()
	// for startup timing. See cmd/pig/startup_trace.go.
	StartupMark func(label string)

	// LoginHeaderOptions contains host-owned operational text and terminal
	// rendering capabilities for an extension-provided login.
	LoginHeaderOptions LoginHeaderOptions

	// BuiltInHeaderLines are the stock text header restored when an extension
	// clears its custom header.
	BuiltInHeaderLines []string

	// LoginVisible applies the startup silence gate to built-in and native
	// extension login presentations.
	LoginVisible bool
}

InteractiveOptions configures the interactive mode.

type InteractiveReplacement

type InteractiveReplacement struct {
	CWD                     string
	SessionDir              string
	Settings                Settings
	SettingsManager         *SettingsManager
	ModelRegistry           *ModelRegistry
	SystemPrompt            string
	SystemPromptOptions     extension.BuildSystemPromptOptions
	AllowedTools            map[string]struct{}
	ActiveBuiltinTools      map[string]struct{}
	ExcludedTools           map[string]struct{}
	ToolRegistryAllowed     map[string]struct{}
	NoBuiltinTools          bool
	PromptPaths             []string
	ThemePaths              []string
	SkillPaths              []string
	Skills                  []*SkillDef
	SkillDiagnostics        []extension.ResourceDiagnostic
	ContextFiles            []ContextFile
	SystemPromptSourcePaths []string
	RebuildSystemPrompt     func(skills []*SkillDef, contextFiles []ContextFile) (string, extension.BuildSystemPromptOptions)
	ResourceSourceInfo      func() map[string]ResourceSourceInfo
	ReloadResources         func() ReloadResourceSnapshot
	ExtensionRunner         *inproc.Runner
	SessionStartEvent       extension.SessionStartEvent
	// ExtensionConflicts are the tool and flag conflicts of the build's final extension set, which Pi lists with the extension load errors.
	ExtensionConflicts      []ExtensionConflict
	BuiltinExtensions       []extension.Extension
	ReloadBuiltinExtensions func() []extension.Extension
	Llama                   *llama.Host
	SubprocessUIBridge      SubprocessUIBridge
	SubprocessHost          SubprocessHost
	ModelLookup             func(providerID, modelID string) *ai.Model
	ModelCatalog            func() []*ai.Model
	ModelClassify           func(context.Context, *ai.ClassifierModel, ai.ClassifierContext, ...ai.ModelsClassifierOptions) ai.ClassifierResult
	ModelGenerateImages     func(context.Context, *ai.ImageModel, ai.ImagesContext, ...ai.ModelsImagesOptions) ai.AssistantImages
	RequestAuthRuntime      *RequestAuthRuntime
}

InteractiveReplacement carries the options of a replacement Session's cwd-bound build, as Pi reads them from the new Session's services. The mode applies it before it rebinds to the Session.

type InteractiveRuntime

type InteractiveRuntime interface {
	NewSession(ctx context.Context, options *extension.NewSessionOptions) (extension.CancelledResult, error)
	// SwitchSession opens path and replaces the Session. projectTrustUI supplies the UI of the destination's project trust prompt, as Pi's projectTrustContextFactory does.
	SwitchSession(ctx context.Context, path, cwdOverride string, projectTrustUI func(cwd string) extension.UIContext, options *extension.SwitchSessionOptions) (extension.CancelledResult, error)
	Fork(ctx context.Context, entryID string, options *extension.ForkOptions) (InteractiveForkResult, error)
	ImportFromJsonl(ctx context.Context, path, cwdOverride string) (extension.CancelledResult, error)
	// ExtensionCommandActions returns the command actions of session with new, fork and switch routed through the runtime.
	ExtensionCommandActions(session InteractiveSessionHandle) extension.CommandActions
	// EmitQuitShutdown emits session_shutdown for quit once; closing the runtime does not repeat it.
	EmitQuitShutdown()
	// SetBeforeSessionReplacement installs the drain that runs after a replacement is approved and before the outgoing Session aborts.
	SetBeforeSessionReplacement(drain func(context.Context) error)
	// SetBeforeSessionInvalidate installs the synchronous hook that runs after session_shutdown and before the outgoing Session's extension contexts go stale.
	SetBeforeSessionInvalidate(hook func())
	// SetRebindSession installs the awaited callback that runs once the replacement Session is installed.
	SetRebindSession(rebind func(ctx context.Context, session InteractiveSessionHandle) error)
}

InteractiveRuntime is the Session replacement contract InteractiveMode needs from the runtime host that created its Session. *coding.Runtime satisfies it through the adapter in cmd/pig; the interface exists because internal/codingagent cannot import coding.

type InteractiveSessionHandle

type InteractiveSessionHandle interface {
	// Agent returns the underlying agent loop.
	Agent() *agent.Agent
	// Inner returns the on-disk session. The local-package type
	// reference (*Session) is the same as *icodingagent.Session
	// from coding/'s point of view.
	Inner() *Session
	// Events returns the agent's streaming event channel. Used by
	// processAgentEvents to drive live UI updates.
	Events() <-chan agent.AgentEvent
	// IsIdle and WaitForIdle observe the Session-owned operation, including work an extension started.
	IsIdle() bool
	WaitForIdle(context.Context) error
	// SetModel swaps the active LLM model mid-session and persists a
	// model_change audit entry.
	SetModel(*ai.Model, ...ModelMutationOptions) error
	// SetModelOnMain dispatches the synchronous state mutation to the owner loop, then waits for extension notifications on the caller. The dispatcher may reject a superseded mutation.
	SetModelOnMain(*ai.Model, ModelMutationOptions, func(func() error) error) error
	// CycleToModel applies a model-cycle selection as SetModel applies a direct one, and reports the selection to extensions with source "cycle".
	CycleToModel(*ai.Model, ...ModelMutationOptions) error
	// ExtensionCompact is the compact action Pi binds for extensions: it starts a manual compaction without waiting, reports the result to options.OnComplete and a failure to options.OnError, and drops the outcome without callbacks.
	ExtensionCompact(*extension.CompactOptions)
	// ExtensionSetModel answers an extension's pi.setModel: false without configured credentials, otherwise it switches as SetModel does and answers true.
	ExtensionSetModel(context.Context, *ai.Model) (bool, error)
	// SetThinkingLevel applies and records reasoning without changing defaults unless Persist is set.
	SetThinkingLevel(ai.ThinkingLevel, ...ModelMutationOptions) error
	// SetSessionName persists and publishes a sanitized Session name.
	SetSessionName(string) error
	// StreamModel starts a mode-independent model operation through the
	// Session-owned runtime.
	StreamModel(context.Context, *ai.Model, ai.Context, ai.StreamOptions) *ai.AssistantMessageEventStream
	// AbortCompaction cancels an in-flight Compact() call. Safe to
	// call when no compaction is running (no-op).
	// Mirrors upstream AgentSession.abortCompaction().
	AbortCompaction()
	// CheckPromptCompaction runs prompt()'s compaction check before a new
	// user message starts a run.
	CheckPromptCompaction(ctx context.Context) error
	// RunAgentPrompt runs one agent run to settlement like Pi's
	// _runAgentPrompt: start seeds it, then automatic retry, overflow and
	// length recovery, threshold compaction, and queued input continue it
	// until nothing asks for another run or ctx is cancelled. The Events
	// consumer must acknowledge the barriers it waits on (see eventBarrier).
	RunAgentPrompt(ctx context.Context, start func(context.Context) ([]agent.AgentMessage, error)) ([]agent.AgentMessage, error)
	// RunInputHandlers runs the extension input handlers for user input
	// (upstream _runInputHandlers); behavior reaches them only while a run
	// is active.
	RunInputHandlers(ctx context.Context, text string, images []ai.ImageContent, source extension.InputSource, behavior string) (string, []ai.ImageContent, bool, error)
	// AbortRetry cancels a pending automatic-retry delay without aborting
	// the run. Mirrors upstream AgentSession.abortRetry().
	AbortRetry()
	// AbortBranchSummary cancels an in-flight branch summarization. Safe
	// to call when no summarization is running (no-op).
	// Mirrors upstream AgentSession.abortBranchSummary().
	AbortBranchSummary()
	// ReplaceInner swaps the underlying on-disk session. Used by /resume
	// to point the SessionHandle at a newly loaded session so tree
	// navigation and compaction operate on the correct entries.
	ReplaceInner(sess *Session)
	// NavigateTree forks the session to targetID with optional branch
	// summarization. Returns NavigateTreeResult.
	// Mirrors upstream AgentSession.navigateTree().
	NavigateTreeHandle(ctx context.Context, targetID string, summarize bool, customInstructions string) (NavigateTreeResult, error)
	// CacheWarmingStatus reports the Session's cache warmer, or nil when it
	// has none. Mirrors upstream AgentSession.cacheWarmingStatus.
	CacheWarmingStatus() *CacheWarmingStatus
	// SetCacheWarmingMode persists the mode and reconciles active warming.
	// Mirrors upstream AgentSession.setCacheWarmingMode.
	SetCacheWarmingMode(CacheWarmingMode) error
	// OnAgentSettled tells the cache warmer that an agent run settled.
	OnAgentSettled()
}

InteractiveSessionHandle is the contract InteractiveMode uses to access a pre-constructed coding session. *coding.Session in the public SDK package satisfies this: its Agent() and Inner() methods have the matching signatures.

We use an interface (rather than importing coding/.Session directly) to break the import cycle: coding/ already imports internal/codingagent for its on-disk Session type, so internal/codingagent cannot import coding/.

main.go (which imports both packages) does the bridging:

sess, _ := coding.NewSession(svcs, opts)
m := codingagent.NewInteractiveMode(codingagent.InteractiveOptions{
    SessionHandle: sess,  // *coding.Session implements this interface
    ...
})

type InteractiveThemeController

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

InteractiveThemeController consumes terminal reports on the owner loop. Dispose cancels and joins all admitted work.

func NewInteractiveThemeController

func NewInteractiveThemeController(ctx context.Context, ui tui.Renderer, options InteractiveThemeControllerOptions) (*InteractiveThemeController, error)

NewInteractiveThemeController resolves the initial theme on the owner loop, as theme-controller.ts's constructor calls initTheme.

func (*InteractiveThemeController) ApplyFromSettings

func (controller *InteractiveThemeController) ApplyFromSettings(ctx context.Context) error

ApplyFromSettings applies the theme setting on the owner loop and starts the terminal color query without waiting for it. WaitForTerminalColors waits for the colors.

func (*InteractiveThemeController) ConsumeInput

func (controller *InteractiveThemeController) ConsumeInput(data string) bool

ConsumeInput consumes terminal reports before viewport or focused-component input. Call it on the owner loop.

func (*InteractiveThemeController) DisableAutoSync

func (controller *InteractiveThemeController) DisableAutoSync()

DisableAutoSync stops terminal color-scheme notifications on the owner loop.

func (*InteractiveThemeController) Dispose

func (controller *InteractiveThemeController) Dispose() error

Dispose runs off-loop while the owner executor is alive. It releases query waiters and joins started work before returning.

type InteractiveThemeControllerOptions

type InteractiveThemeControllerOptions struct {
	GetSettingsManager  func() *SettingsManager
	ShowError           func(string)
	OnChanged           func()
	InitialThemeSetting *string
	Output              io.Writer
	RunOnMain           func(context.Context, func()) error
}

InteractiveThemeControllerOptions binds the shared theme state machine to a presentation owner and settings store. Callbacks run on the UI owner.

type InteractiveTuiOptions

type InteractiveTuiOptions struct {
	TuiMode                string
	ShowHardwareCursor     *bool
	LogDirectory           string
	Output                 io.Writer
	OnRightClickPaste      func()
	FullscreenCopyOnSelect *bool
	// FullscreenWheelScrollLines is the fullscreen renderer's wheel line count; nil is auto (tui-renderer.ts:38).
	FullscreenWheelScrollLines *tui.WheelScrollLines
	OpenURL                    func(string) error
	CopySelection              func(string) error
}

InteractiveTuiOptions supplies the shared paint surface. The driver owns terminal input, dispatch and shutdown. Nil Output selects the process terminal; nil ShowHardwareCursor preserves the renderer's construction default.

type KeyID

type KeyID = string

type KeybindingConflict

type KeybindingConflict struct {
	Key     KeyID
	Actions []string
}

type KeybindingDefinition

type KeybindingDefinition struct {
	DefaultKeys []KeyID
	Description string
}

type KeybindingsManager

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

func DefaultKeybindingsManager

func DefaultKeybindingsManager() *KeybindingsManager

func NewKeybindingsManager

func NewKeybindingsManager(agentDir string) *KeybindingsManager

func (*KeybindingsManager) Conflicts

func (km *KeybindingsManager) Conflicts() []KeybindingConflict

func (*KeybindingsManager) DisplayFor

func (km *KeybindingsManager) DisplayFor(action string) string

DisplayFor returns a human-readable key hint for the first binding of the given action (e.g. "Alt+Up"). Returns the raw KeyID if no display mapping exists.

func (*KeybindingsManager) ExtensionKeybindingTable

func (km *KeybindingsManager) ExtensionKeybindingTable() map[string]any

ExtensionKeybindingTable supplies the platform definitions and user overrides used by extension editor and UI factories.

func (*KeybindingsManager) Get

func (km *KeybindingsManager) Get(action string) []KeyID

func (*KeybindingsManager) KeyText

func (km *KeybindingsManager) KeyText(action string) string

KeyText returns the un-capitalized display text for every key bound to action, joined by "/", mirroring upstream keyText (keybinding-hints.ts): getKeys → formatKeyText without capitalization. Used for the startup keybinding hints.

func (*KeybindingsManager) Matches

func (km *KeybindingsManager) Matches(input, action string) bool

func (*KeybindingsManager) MatchesEditorHistory

func (km *KeybindingsManager) MatchesEditorHistory(input string) bool

MatchesEditorHistory reports whether input matches an explicit tui.editor.historyPrevious or historyNext binding. The focused editor gives those precedence over app actions (custom-editor.ts handleInput), so a user can bind ctrl+p to history although it cycles models by default.

func (*KeybindingsManager) Reload

func (km *KeybindingsManager) Reload() error

func (*KeybindingsManager) Resolve

func (km *KeybindingsManager) Resolve(input string) string

func (*KeybindingsManager) ResolvedBindings

func (km *KeybindingsManager) ResolvedBindings() map[string][]string

ResolvedBindings returns a detached snapshot of every canonical action's resolved key IDs for extension-shortcut conflict checks.

func (*KeybindingsManager) Save

func (km *KeybindingsManager) Save(path string) error

func (*KeybindingsManager) SetUserBindings

func (km *KeybindingsManager) SetUserBindings(bindings map[string][]KeyID)

type LabelEntry

type LabelEntry struct {
	SessionEntryBase
	TargetID string  `json:"targetId"`
	Label    *string `json:"label"`
}

LabelEntry is upstream's "user-renamed this branch" marker. Carries nil Label to delete a previously-set label.

type LoadPromptTemplatesResult

type LoadPromptTemplatesResult struct {
	Templates   []PromptTemplate
	Diagnostics []extension.ResourceDiagnostic
}

LoadPromptTemplatesResult carries loaded commands and file-read or YAML warnings.

func LoadPromptTemplates

func LoadPromptTemplates(cwd, agentDir string, extraPaths ...string) LoadPromptTemplatesResult

LoadPromptTemplates loads user, project, and explicit prompt paths.

type LoadSkillsFromDirOptions

type LoadSkillsFromDirOptions struct {
	Dir    string
	Source string
}

LoadSkillsFromDirOptions selects one skill directory and its provenance source.

type LoadSkillsOptions

type LoadSkillsOptions struct {
	CWD             string
	AgentDir        string
	SkillPaths      []string
	IncludeDefaults bool
}

LoadSkillsOptions selects default and explicit skill paths in their precedence order.

type LoadSkillsResult

type LoadSkillsResult struct {
	Skills      []*SkillDef
	Diagnostics []extension.ResourceDiagnostic
}

LoadSkillsResult contains accepted skills and ordered validation/collision diagnostics.

func LoadSkills

func LoadSkills(options LoadSkillsOptions) (LoadSkillsResult, error)

LoadSkills resolves explicit paths, loads defaults when requested, and keeps the first public name and physical file. Invalid path syntax returns an error; read/metadata failures and name collisions remain diagnostics.

func LoadSkillsFromDir

func LoadSkillsFromDir(options LoadSkillsFromDirOptions) LoadSkillsResult

LoadSkillsFromDir scans direct root Markdown files and nested SKILL.md files. A directory's own SKILL.md takes precedence, and invalid declared skills retain diagnostics while ordinary documentation is ignored.

type LoginHeaderOptions

type LoginHeaderOptions struct {
	OperationalLines []string
	TrueColor        bool
	GlyphFree        bool
	ColorOverrides   map[byte]color.RGBA
}

LoginHeaderOptions contains host-owned values used by the native login template. OperationalLines are rendered after the extension-owned identity.

type MarkdownSettings

type MarkdownSettings struct {
	CodeBlockIndent string `json:"codeBlockIndent,omitempty"`
	Mermaid         string `json:"mermaid,omitempty"`
}

MarkdownSettings mirrors upstream MarkdownSettings. Mirrors upstream settings-manager.ts MarkdownSettings.

type MessageEntry

type MessageEntry struct {
	SessionEntryBase
	Message agent.AgentMessage `json:"message"`
}

type MissingSessionCwdError

type MissingSessionCwdError struct{ Issue SessionCwdIssue }

func (*MissingSessionCwdError) Error

func (err *MissingSessionCwdError) Error() string

type ModelChangeEntry

type ModelChangeEntry struct {
	SessionEntryBase
	Provider string `json:"provider"`
	ModelID  string `json:"modelId"`
}

type ModelEntry

type ModelEntry struct {
	ProviderID       string
	ModelID          string
	APIKey           string
	BaseURL          string
	DisplayName      string
	API              string            // "openai-completions" | "anthropic-messages" | etc.
	Headers          map[string]string // resolved request headers from provider/model configuration
	ModelHeaders     map[string]string // intrinsic public Model.headers from the generated catalog
	AuthHeader       bool              // put API key in Authorization header (for custom providers)
	Compat           *ai.OpenAICompat  // compat flags for OpenAI-compatible providers
	Reasoning        bool              // whether the model supports reasoning/thinking
	ThinkingLevelMap ai.ThinkingLevelMap
	SamplingParams   map[string]any
	// SamplingParamsByThinkingLevel overrides SamplingParams for the effective Pi thinking level.
	SamplingParamsByThinkingLevel ai.SamplingParamsByThinkingLevel
	InputLimits                   *ai.ModelInputLimits
	Input                         []string // ["text"] or ["text","image"]
	ContextWindow                 int      // default: 128000
	MaxTokens                     int      // default: 16384
	InputCost                     float64
	OutputCost                    float64
	CacheReadCost                 float64
	CacheWriteCost                float64
	CostTiers                     []ai.CostTier
	PromptCache                   ai.ModelPromptCache
	Env                           map[string]string // provider-scoped env overrides (auth.json env)
	Insecure                      bool              // skip TLS verification (self-signed/internal-CA on-prem endpoints)
}

ModelEntry holds the resolved configuration for a single provider+model. Produced by ModelRegistry.Resolve from the upstream models.json schema.

func NativeModelEntry

func NativeModelEntry(model *ai.Model) ModelEntry

NativeModelEntry lowers native model data to the configured backend representation without resolving credentials.

type ModelMutationOptions

type ModelMutationOptions struct {
	Persist bool
}

ModelMutationOptions controls whether a Session mutation also saves a global default.

type ModelOperationBindings

type ModelOperationBindings struct {
	CurrentModel  func() *ai.Model
	ModelLookup   func(providerID, modelID string) *ai.Model
	ModelCatalog  func() []*ai.Model
	Registry      *ModelRegistry
	ModelBuilder  func(spec string) (*ai.Model, error)
	SessionHandle InteractiveSessionHandle
	// Classify is the Session runtime's classify; an extension's ctx.modelRegistry.classify reaches it. Nil answers an error result.
	Classify func(context.Context, *ai.ClassifierModel, ai.ClassifierContext, ...ai.ModelsClassifierOptions) ai.ClassifierResult
	// GenerateImages is the Session runtime's generateImages; an extension's ctx.modelRegistry.generateImages reaches it. Nil answers an error result.
	GenerateImages func(context.Context, *ai.ImageModel, ai.ImagesContext, ...ai.ModelsImagesOptions) ai.AssistantImages
	Transport      ai.Transport
}

type ModelOperationBridge

type ModelOperationBridge interface {
	SetHostAction(key string, fn any)
	PublishModelCatalog()
}

type ModelPriceSource

type ModelPriceSource func(provider, modelID string) float64

ModelPriceSource returns cache-read dollars per million tokens, or zero for an unknown model. It is the Go projection of cache-stats.ts's pricing-only getModel dependency.

type ModelRegistry

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

ModelRegistry resolves model configurations from models.json and environment. Mirrors upstream model-registry.ts.

func NewModelRegistry

func NewModelRegistry(agentDir string) *ModelRegistry

NewModelRegistry creates a registry, loading from <agent-dir>/models.json if present.

func NewModelRegistryWithModelsPath

func NewModelRegistryWithModelsPath(modelsPath string) *ModelRegistry

NewModelRegistryWithModelsPath loads the explicitly selected model configuration. An empty path disables the file. Ports packages/coding-agent/src/core/model-runtime.ts:176-184.

func (*ModelRegistry) AvailableProviderCount

func (r *ModelRegistry) AvailableProviderCount() int

AvailableProviderCount returns the number of distinct providers with configured auth. Used by the footer to decide whether to show the provider chip. Mirrors upstream updateAvailableProviderCount (interactive-mode.ts:3858-3862).

func (*ModelRegistry) AwaitModelTasks

func (r *ModelRegistry) AwaitModelTasks(ctx context.Context, tasks ...func(context.Context) error) error

AwaitModelTasks mirrors Promise.all: first rejection settles the waiter, success requires every task, and an owned coordinator joins all remaining tasks without cancelling them on rejection.

func (*ModelRegistry) BugReportProviderInfo

func (r *ModelRegistry) BugReportProviderInfo(providerID string) *BugReportProvider

BugReportProviderInfo describes providerID from models.json and extension registrations. It returns nil when the registry is nil.

func (*ModelRegistry) CacheReadPrice

func (r *ModelRegistry) CacheReadPrice(providerID, modelID string) float64

CacheReadPrice reads composed model pricing without resolving credentials, executing configuration commands, or performing network work.

func (*ModelRegistry) CheckRegistryAuth

func (r *ModelRegistry) CheckRegistryAuth(ctx context.Context, id string) (*ai.AuthCheck, error)

CheckRegistryAuth checks provider configuration without resolving command-backed fallback keys.

func (*ModelRegistry) CloseModelTasks

func (r *ModelRegistry) CloseModelTasks()

CloseModelTasks stops admission, cancels the owner, and waits for admitted jobs and failed Promise siblings to drain. It also cancels the native Models collection's active refreshes, including a queued registration refresh's provider callbacks, without waiting for caller-owned Models operations such as in-flight streams or logins. Call it outside model callbacks.

func (*ModelRegistry) CompatibilityRequestHeaders

func (r *ModelRegistry) CompatibilityRequestHeaders(model *ai.Model) (ai.ProviderHeaders, bool, error)

CompatibilityRequestHeaders resolves configured headers even when no API key is configured.

func (*ModelRegistry) ConfiguredRequestAuthStatus

func (r *ModelRegistry) ConfiguredRequestAuthStatus(providerID string) (ai.AuthStatus, bool)

ConfiguredRequestAuthStatus reports explicit provider configuration without reading credentials or executing command values. Like Pi provider-composer.ts:597-610, a "$VAR" key is evaluated against the process environment, never a stored credential's env, so this synchronous snapshot getter performs no credential I/O.

func (*ModelRegistry) ExtensionProviderAuth

func (r *ModelRegistry) ExtensionProviderAuth(ctx context.Context, providerID string) (*ai.AuthResult, error)

ExtensionProviderAuth mirrors upstream ModelRuntime.getAuth(provider): the provider's request auth, or nil when it has none.

func (*ModelRegistry) ExtensionProviderAuthStatus

func (r *ModelRegistry) ExtensionProviderAuthStatus(providerID string) ai.AuthStatus

ExtensionProviderAuthStatus mirrors upstream ModelRuntime.getProviderAuthStatus: a runtime API key, then a stored credential, then the API key an extension registration or models.json configures, then the provider's ambient credentials.

func (*ModelRegistry) ExtensionRefresh

func (r *ModelRegistry) ExtensionRefresh(ctx context.Context, allowNetwork *bool, providers []string, force *bool) CatalogRefreshResult

ExtensionRefresh mirrors upstream ModelRuntime.refresh: reload models.json, then refresh the provider catalogs, from the network only when allowed.

func (*ModelRegistry) GetAll

func (r *ModelRegistry) GetAll() []ModelEntry

GetAll returns explicit models and configured overlays for exact generated identities; dynamic providers take precedence over models.json.

func (*ModelRegistry) GetAllModelData

func (r *ModelRegistry) GetAllModelData() []*ai.Model

GetAllModelData returns the composed catalog in provider order without running credential configuration expressions.

func (*ModelRegistry) GetAllProviderModelData

func (r *ModelRegistry) GetAllProviderModelData() []ai.AnyModel

GetAllProviderModelData lists the models of every type of every provider in provider order.

func (*ModelRegistry) GetAvailable

func (r *ModelRegistry) GetAvailable() []ModelEntry

GetAvailable returns all model entries from dynamic (extension-registered) and models.json providers that have configured auth (API key or OAuth credentials). Mirrors upstream ModelRegistry.getAvailable() (model-registry.ts:2266), which filters a single #models list merged from built-ins, models.json custom overlays, and runtime extension overlays -- not just extension-registered providers. A provider name registered dynamically takes precedence over a models.json entry of the same name, matching Resolve()'s lookup order.

func (*ModelRegistry) GetAvailableAllModelDataContext

func (r *ModelRegistry) GetAvailableAllModelDataContext(ctx context.Context, providerID string) ([]ai.AnyModel, error)

GetAvailableAllModelDataContext lists the models of every type whose provider has working credentials, checking providers concurrently like GetAvailableModelDataContext. Chat models follow the provider's chat availability; every other model type is kept (models.ts getAllAvailable).

func (*ModelRegistry) GetAvailableModelData

func (r *ModelRegistry) GetAvailableModelData() []*ai.Model

GetAvailableModelData returns the available catalog without request authentication or backend construction.

func (*ModelRegistry) GetAvailableModelDataContext

func (r *ModelRegistry) GetAvailableModelDataContext(ctx context.Context, providerID string) ([]*ai.Model, error)

GetAvailableModelDataContext awaits provider auth and account filtering without resolving request-only credentials or constructing backend clients. The first rejection returns immediately while the shared owner drains other providers.

func (*ModelRegistry) GetNativeModels

func (r *ModelRegistry) GetNativeModels(id ...string) []*ai.Model

GetNativeModels returns provider-owned model data without building backend clients.

func (*ModelRegistry) GetProvider

func (r *ModelRegistry) GetProvider(id string) *ai.ModelsProvider

GetProvider returns a native or composed provider by exact ID.

func (*ModelRegistry) GetProviderAllModelData

func (r *ModelRegistry) GetProviderAllModelData(id string) []ai.AnyModel

GetProviderAllModelData lists the models of every type of one provider without resolving credentials.

func (*ModelRegistry) GetProviderAuth

func (r *ModelRegistry) GetProviderAuth(ctx context.Context, id string) (*ai.AuthResult, error)

GetProviderAuth resolves native provider auth against the shared credential store.

func (*ModelRegistry) GetProviderAuthChecks

func (r *ModelRegistry) GetProviderAuthChecks(ctx context.Context) (map[string]*ai.AuthCheck, error)

GetProviderAuthChecks starts every provider's current auth check, including empty catalogs. The first rejection returns immediately; Services retains and drains the remaining checks.

func (*ModelRegistry) GetProviderAuthStatus

func (r *ModelRegistry) GetProviderAuthStatus(providerID string) ai.AuthStatus

func (*ModelRegistry) GetProviderDisplayName

func (r *ModelRegistry) GetProviderDisplayName(providerID string) string

func (*ModelRegistry) GetProviderModelData

func (r *ModelRegistry) GetProviderModelData(id string) []*ai.Model

GetProviderModelData composes metadata without resolving keys, headers, or backend clients.

func (*ModelRegistry) GetRegisteredNativeProvider

func (r *ModelRegistry) GetRegisteredNativeProvider(id string) *ai.ModelsProvider

GetRegisteredNativeProvider returns the caller's original native registration.

func (*ModelRegistry) GetRegisteredProviderConfig

func (r *ModelRegistry) GetRegisteredProviderConfig(id string) *ProviderConfigInput

GetRegisteredProviderConfig returns the active core provider-registration input.

func (*ModelRegistry) GetRegisteredProviderIDs

func (r *ModelRegistry) GetRegisteredProviderIDs() []string

GetRegisteredProviderIDs preserves native registration order.

func (*ModelRegistry) GetTypedProvider

func (r *ModelRegistry) GetTypedProvider(id string, fallback ai.ModelsStreamFunction) *ai.ModelsProvider

GetTypedProvider returns the composed provider with the given ID: a registered native or composed provider, else the built-in provider composed with models.json and legacy registrations, streaming through fallback. It returns nil for an unknown provider.

func (*ModelRegistry) HasAnyKey

func (r *ModelRegistry) HasAnyKey(providerID string) bool

HasAnyKey reports whether the registry has at least one entry for the given provider with a non-empty (post-resolve) APIKey, or the environment configures its auth.

func (*ModelRegistry) HasConfiguredAuth

func (r *ModelRegistry) HasConfiguredAuth(providerID string) bool

HasConfiguredAuth reports whether the provider has either an API key (from env, models.json, or dynamic registration) or stored OAuth credentials. Mirrors upstream ModelRegistry.hasConfiguredAuth() (model-registry.ts:605-612).

func (*ModelRegistry) HasGeneratedModel

func (r *ModelRegistry) HasGeneratedModel(providerID, modelID string) bool

HasGeneratedModel reports whether provider composition retains one generated identity.

func (*ModelRegistry) HasModelDefinition

func (r *ModelRegistry) HasModelDefinition(providerID, modelID string) bool

HasModelDefinition reports whether provider composition exposes providerID/modelID through an explicit models list.

func (*ModelRegistry) HasRegisteredProvider

func (r *ModelRegistry) HasRegisteredProvider(providerID string) bool

HasRegisteredProvider reports whether an extension owns an overlay for providerID.

func (*ModelRegistry) HoldRegistrationRefresh

func (r *ModelRegistry) HoldRegistrationRefresh() (release func())

HoldRegistrationRefresh keeps StartRegistrationRefresh from starting the queued pass until the returned release function has run for every hold; the registrations only queue. A caller that loads several extension factories holds while it loads, as Pi queues their provider registrations and flushes them only after every factory has finished (agent-session-services.ts:158-182; the reload path's bindCore flush). An awaited yield ignores holds, because the awaiting caller has ended its turn. Releasing the last hold starts the queued pass. Release is idempotent.

func (*ModelRegistry) ListCredentials

func (r *ModelRegistry) ListCredentials(ctx context.Context) ([]ai.CredentialInfo, error)

ListCredentials enumerates the runtime overlay and shared credential storage.

func (*ModelRegistry) LoadError

func (r *ModelRegistry) LoadError() string

LoadError returns model configuration read, parse, and schema errors with the source path. Provider refresh failures surface through the Model Runtime's availability error, as in Pi.

func (*ModelRegistry) LoginNativeProvider

func (r *ModelRegistry) LoginNativeProvider(ctx context.Context, id string, kind ai.AuthType, interaction ai.AuthInteraction, options ...ai.LoginOptions) (ai.Credential, error)

LoginNativeProvider serializes same-provider login and logout through persistence and local synchronization. It logs in the composed provider GetTypedProvider returns for the ID, a built-in or models.json provider included, and passes the optional LoginOptions to the provider's login. A synchronization failure returns the committed credential with CredentialSynchronizationError.

func (*ModelRegistry) LogoutNativeProvider

func (r *ModelRegistry) LogoutNativeProvider(ctx context.Context, id string) error

LogoutNativeProvider serializes deletion and local synchronization with other credential operations for this provider. A synchronization failure reports that deletion committed.

func (*ModelRegistry) ModelTaskContext

func (r *ModelRegistry) ModelTaskContext(ctx context.Context) context.Context

ModelTaskContext links operation cancellation to the Services lifetime while preserving caller values and cancellation causes. It does not cancel a retained signal when an operation settles.

func (*ModelRegistry) NativeModels

func (r *ModelRegistry) NativeModels() *ai.Models

NativeModels returns the provider-owned collection sharing this registry's credentials and ModelsStore.

func (*ModelRegistry) NativeProvider

func (r *ModelRegistry) NativeProvider(id string) *extension.NativeProvider

func (*ModelRegistry) NativeProviderAuth

func (r *ModelRegistry) NativeProviderAuth(ctx context.Context, id string, overrides ai.AuthResolutionOverrides) (*ai.AuthResult, error)

NativeProviderAuth resolves auth and commits a rotated credential atomically. The credential-store lock spans the reverse callback just as Pi's modify spans OAuth refresh. Missing credentials and callback failures never fall back.

func (*ModelRegistry) ObserveChanges

func (r *ModelRegistry) ObserveChanges(notify func()) func()

ObserveChanges subscribes without replacing the host's catalog listener. Detach drains an in-flight callback and prevents later admission.

func (*ModelRegistry) ProviderInsecure

func (r *ModelRegistry) ProviderInsecure(providerID string) bool

ProviderInsecure returns the configured transport flag without resolving credentials or headers.

func (*ModelRegistry) ProviderIsSubscription

func (r *ModelRegistry) ProviderIsSubscription(providerID string) bool

ProviderIsSubscription reads the currently composed provider's OAuth capability without reading credentials.

func (*ModelRegistry) ProviderStreamSimple

func (r *ModelRegistry) ProviderStreamSimple(name string) extension.ProviderStreamSimple

ProviderStreamSimple returns the custom stream callback owned by this registry's current provider registration. It never installs a global API handler.

func (*ModelRegistry) RadiusAPIKey

func (r *ModelRegistry) RadiusAPIKey(ctx context.Context, providerID string) (string, error)

RadiusAPIKey resolves the request credential of a Radius provider: a runtime key, a stored OAuth token (refreshed when expired) or API key, then RADIUS_API_KEY. Store reads and token refreshes honor ctx; storage failures are returned instead of falling through to ambient credentials.

func (*ModelRegistry) RadiusOAuth

func (r *ModelRegistry) RadiusOAuth(providerID string) (*ai.RadiusOAuth, bool)

RadiusOAuth returns the OAuth flow of the Radius provider providerID.

func (*ModelRegistry) RadiusOAuthFlows

func (r *ModelRegistry) RadiusOAuthFlows() []*ai.RadiusOAuth

RadiusOAuthFlows returns every configured Radius OAuth flow, sorted by ID.

func (*ModelRegistry) ReadCredential

func (r *ModelRegistry) ReadCredential(ctx context.Context, providerID string) (*ai.Credential, error)

ReadCredential reads a provider credential through the runtime overlay.

func (*ModelRegistry) Refresh

func (r *ModelRegistry) Refresh()

Refresh reloads models.json from disk, preserves dynamic provider registrations, and restores stored dynamic catalogs without network access.

func (*ModelRegistry) RefreshCatalogs

func (r *ModelRegistry) RefreshCatalogs(ctx context.Context, options CatalogRefreshOptions) CatalogRefreshResult

RefreshCatalogs mirrors ModelRuntime.refresh for dynamic providers: each selected provider restores its stored catalog and, when allowed, refreshes it from the network. A newer refresh of the same provider supersedes an older one. Errors of cancelled or superseded refreshes are not reported.

func (*ModelRegistry) RefreshModelRuntime

func (r *ModelRegistry) RefreshModelRuntime(ctx context.Context, options ai.ModelsRefreshOptions) ai.ModelsRefreshResult

RefreshModelRuntime reloads configuration and refreshes every selected provider through the registry's shared coordinator. A refresh over every provider first yields to the queued registration refresh, and a provider-scoped refresh covers the queued registrations of its own providers (model-runtime.ts:750,788,796).

func (*ModelRegistry) RefreshNativeProviders

func (r *ModelRegistry) RefreshNativeProviders(ctx context.Context, options ai.ModelsRefreshOptions) ai.ModelsRefreshResult

RefreshNativeProviders awaits native catalog publication and the bound availability snapshot before returning to credential synchronization.

func (*ModelRegistry) RegisterNativeModelsProvider

func (r *ModelRegistry) RegisterNativeModelsProvider(provider *ai.ModelsProvider) error

RegisterNativeModelsProvider replaces legacy registration state with the native catalog/auth/API callbacks, while retaining models.json overlays. It returns without authenticating or waiting for availability: the bound projection republishes the catalog, and the local refresh is queued for the caller's next yield.

func (*ModelRegistry) RegisterNativeProvider

func (r *ModelRegistry) RegisterNativeProvider(ctx context.Context, p *extension.NativeProvider) error

RegisterNativeProvider installs the object and model snapshot and queues the local refresh, as Pi's registerNativeProvider does. It performs no authentication and calls no provider callback; both happen in the queued refresh. The bound availability projection runs before listeners are notified.

func (*ModelRegistry) RegisterProvider

func (r *ModelRegistry) RegisterProvider(name string, configMap extension.ProviderConfig) error

RegisterProvider validates the incoming configuration before changing the registry. Legacy entry points merge without dropping omitted callbacks; a native registration is displaced only after validation succeeds. A stored or configured provider is provisionally available in the Services snapshot before observers run; its availability refresh is scheduled after them.

func (*ModelRegistry) RegisterProviderInput

func (r *ModelRegistry) RegisterProviderInput(id string, input ProviderConfigInput, fallback ai.ModelsStreamFunction) error

RegisterProviderInput composes legacy model and OAuth callbacks over built-in/configured metadata. Both legacy entry points share merge state, while a prior native registration is replaced. A configured or stored-credential registration is provisionally available until its queued local refresh runs.

func (*ModelRegistry) RemoveRuntimeAPIKey

func (r *ModelRegistry) RemoveRuntimeAPIKey(providerID string)

RemoveRuntimeAPIKey drops providerID's runtime key. Mirrors upstream ModelRuntime.removeRuntimeApiKey.

func (*ModelRegistry) RequestAuthHeaders

func (r *ModelRegistry) RequestAuthHeaders(model *ai.Model, headers ai.ProviderHeaders) ai.ProviderHeaders

RequestAuthHeaders folds configured HTTP header names in declaration order while compatibility auth results retain their original keys and null values.

func (*ModelRegistry) Resolve

func (r *ModelRegistry) Resolve(providerID, modelID string) (ModelEntry, bool)

Resolve returns a ModelEntry for the given provider+model combination. Resolution order:

  1. Custom model definition in models.json (provider → models[])
  2. Model override in models.json (provider → modelOverrides[modelID])
  3. Provider-level defaults from models.json (baseUrl, apiKey, compat, headers)
  4. Environment variables (PROVIDER_API_KEY)

Mirrors upstream parseModels + request-auth resolution.

func (*ModelRegistry) ResolveCompatibilityModelAuth

func (r *ModelRegistry) ResolveCompatibilityModelAuth(ctx context.Context, model *ai.Model) (*ai.AuthResult, error)

ResolveCompatibilityModelAuth returns request credentials or unconfigured compatibility headers, preserving nullable header suppression and the facade's error messages.

func (*ModelRegistry) ResolveGeneratedModel

func (r *ModelRegistry) ResolveGeneratedModel(providerID, modelID string, generated *ai.GeneratedModel) ModelEntry

ResolveGeneratedModel layers provider configuration and a matching model override onto one generated model.

func (*ModelRegistry) ResolveRegistryModelAuth

func (r *ModelRegistry) ResolveRegistryModelAuth(ctx context.Context, model *ai.Model, overrides ...ai.AuthResolutionOverrides) (*ai.AuthResult, error)

ResolveRegistryModelAuth preserves nullable provider headers and resolves model headers after authentication.

func (*ModelRegistry) ResolveRegistryProviderAuth

func (r *ModelRegistry) ResolveRegistryProviderAuth(ctx context.Context, id string, overrides ...ai.AuthResolutionOverrides) (*ai.AuthResult, error)

ResolveRegistryProviderAuth resolves provider credentials only at the request boundary.

func (*ModelRegistry) ResolveRegistryTypedModelAuth

func (r *ModelRegistry) ResolveRegistryTypedModelAuth(ctx context.Context, model ai.AnyModel, overrides ...ai.AuthResolutionOverrides) (*ai.AuthResult, error)

ResolveRegistryTypedModelAuth resolves request auth for an image or classifier model: provider auth plus the model's own headers and the configured headers of its definition.

func (*ModelRegistry) RuntimeAPIKey

func (r *ModelRegistry) RuntimeAPIKey(providerID string) (string, bool)

RuntimeAPIKey returns the non-persistent API key set for providerID.

func (*ModelRegistry) RuntimeModels

func (r *ModelRegistry) RuntimeModels() []RuntimeModel

RuntimeModels returns composed selection metadata without resolving request authentication or copying unused request capabilities.

func (*ModelRegistry) SetAuthStorage

func (r *ModelRegistry) SetAuthStorage(auth *ai.AuthStorage)

SetAuthStorage wires the auth.json credential store for auth-aware filtering. A nil storage leaves the registry without stored credentials.

func (*ModelRegistry) SetAvailabilityRefresh

func (r *ModelRegistry) SetAvailabilityRefresh(refresh func(context.Context, []string) ai.ModelsRefreshResult)

SetAvailabilityRefresh binds the Services-owned snapshot reconciler before the registry is shared with consumers. It runs after catalog publication and inside credential synchronization.

func (*ModelRegistry) SetAvailabilitySnapshot

func (r *ModelRegistry) SetAvailabilitySnapshot(configured func(providerID string) bool, sync func(providerID string, provisional *ai.AuthCheck, providerOrder func() []string))

SetAvailabilitySnapshot binds the Services-owned availability snapshot before the registry is shared with consumers. configured reports configured auth for Models-collection providers. Registration and removal call sync with a reader of the catalog's provider order after the catalog commits and before change observers run. A nil provisional check grants no availability before the queued refresh. upstream: packages/coding-agent/src/core/model-runtime.ts:registerProvider

func (*ModelRegistry) SetCatalogBaseURL

func (r *ModelRegistry) SetCatalogBaseURL(baseURL string)

SetCatalogBaseURL selects the remote catalog endpoint; empty selects DefaultCatalogBaseURL. upstream: model-runtime.ts:CreateModelRuntimeOptions.catalogBaseUrl

func (*ModelRegistry) SetChangeListener

func (r *ModelRegistry) SetChangeListener(notify func()) func()

SetChangeListener replaces the callback invoked after a committed registry change and returns a draining detach function.

func (*ModelRegistry) SetCredentialStore

func (r *ModelRegistry) SetCredentialStore(store ai.CredentialStore)

SetCredentialStore wires the credential store for auth-aware filtering and resets the runtime-key overlay. Call it before using the registry.

func (*ModelRegistry) SetModelsStore

func (r *ModelRegistry) SetModelsStore(store ai.ModelsStore)

SetModelsStore replaces the dynamic catalog store.

func (*ModelRegistry) SetProvider

func (r *ModelRegistry) SetProvider(name string, configMap extension.ProviderConfig)

SetProvider replaces a runtime-registered provider in one committed change, so fields absent from config are cleared rather than kept. The built-in llama.cpp provider republishes its resolved auth and catalog this way. Each republication projects availability and queues the local refresh.

func (*ModelRegistry) SetRuntimeAPIKey

func (r *ModelRegistry) SetRuntimeAPIKey(providerID, apiKey string)

SetRuntimeAPIKey installs a non-persistent API key for providerID. It acts as a stored api_key credential that is never written to auth.json. Mirrors upstream ModelRuntime.setRuntimeApiKey over RuntimeCredentials.

func (*ModelRegistry) StartModelTask

func (r *ModelRegistry) StartModelTask(ctx context.Context, work func(context.Context)) bool

StartModelTask admits background model work under the caller and Services lifetimes. False means the owner is closed or the context is nil. Work must report errors through its owning operation and must not close its own Services.

func (*ModelRegistry) StartRegistrationRefresh

func (r *ModelRegistry) StartRegistrationRefresh(ctx context.Context)

StartRegistrationRefresh starts the queued registration refresh, unless a hold is active, and does not wait for it. A caller whose operation is scoped to some providers and does not itself refresh their catalogs uses it (availability of one provider, its auth check, its login): Pi launches the registration refresh unawaited (model-runtime.ts:750,788,796), and those calls select only their own providers, so they never wait for another provider's callbacks. Services.Close cancels and drains the pass. Ports packages/coding-agent/src/core/model-runtime.ts:registerNativeProvider,registerProvider,unregisterProvider.

func (*ModelRegistry) UnregisterProvider

func (r *ModelRegistry) UnregisterProvider(name string)

UnregisterProvider removes a runtime registration, projects the remaining catalog into the Services snapshot, notifies observers, and queues the local refresh. Pi does this for every call, including a name with no registration. upstream: packages/coding-agent/src/core/model-runtime.ts:unregisterProvider

func (*ModelRegistry) YieldToRegistrationRefresh

func (r *ModelRegistry) YieldToRegistrationRefresh(ctx context.Context)

YieldToRegistrationRefresh runs the queued registration refresh before the caller's own awaited operation, as Pi's earlier-queued continuation runs before a later one, and waits for it. Only a caller whose operation covers every provider waits: Pi's refresh over every provider awaits each provider's callbacks, so its caller would wait for the same ones. The caller stops waiting when ctx ends, and a caller whose ctx has already ended only starts the pass; the pass then continues under the Services lifetime, and Services.Close cancels and drains it. A caller that finds nothing queued returns at once, even while a pass runs, so a provider callback that calls back into the runtime cannot deadlock the pass. The pass itself never yields. Ports packages/coding-agent/src/core/model-runtime.ts:registerNativeProvider,registerProvider,unregisterProvider.

type ModelResolverRuntime

type ModelResolverRuntime interface {
	GetModels(providerID string) []RuntimeModel
	HasConfiguredAuth(providerID string) bool
}

ModelResolverRuntime supplies the catalog and configured-auth observations used by CLI resolution. Selection does not resolve credentials or refresh the catalog.

type ModelScopeDiagnostic

type ModelScopeDiagnostic struct {
	Type    string
	Code    string
	Message string
	Pattern string
}

ModelScopeDiagnostic identifies a pattern that did not resolve cleanly.

type NavigateTreeResult struct {
	EditorText string
	Cancelled  bool
	Aborted    bool
}

NavigateTreeResult is the TUI-facing result of a tree navigation operation. Re-exported here (from coding.NavigateTreeResult) so slash handlers don't need to import the public SDK package (cycle prevention).

type NoopUI

type NoopUI struct{}

NoopUI is a non-interactive ExtensionUIContext for headless mode.

func (NoopUI) Confirm

func (NoopUI) Confirm(_, _ string) bool

func (NoopUI) Input

func (NoopUI) Input(_, _ string) (string, bool)

func (NoopUI) Notify

func (NoopUI) Notify(_, _ string)

func (NoopUI) Select

func (NoopUI) Select(_ string, _ []string) (string, bool)

func (NoopUI) SetStatus

func (NoopUI) SetStatus(_, _ string)

func (NoopUI) SetWidget

func (NoopUI) SetWidget(_ string, _ []string)

type PackageManagerOwner

type PackageManagerOwner string

PackageManagerOwner names a package manager proven to own an installation.

type PackageSource

type PackageSource struct {
	Source     string   `json:"source,omitempty"`
	Autoload   *bool    `json:"autoload,omitempty"`
	Extensions []string `json:"extensions,omitempty"`
	Skills     []string `json:"skills,omitempty"`
	Prompts    []string `json:"prompts,omitempty"`
	Themes     []string `json:"themes,omitempty"`

	// WasObject tracks whether the JSON was an object (vs bare string).
	// Upstream considers ANY object-format package as "filtered"
	// (typeof pkg === "object"), even if no filter fields are set.
	WasObject bool `json:"-"`
}

PackageSource mirrors upstream settings-manager.ts PackageSource. JSON accepts either a bare string source or an object with resource filters and optional autoload selection.

func (PackageSource) Filtered

func (p PackageSource) Filtered() bool

Filtered reports whether the package was specified in object form. Upstream: `filtered: typeof pkg === "object"`: any object form is filtered. For programmatically constructed sources, filter fields also signal filtering.

func (PackageSource) MarshalJSON

func (p PackageSource) MarshalJSON() ([]byte, error)

MarshalJSON preserves upstream's string-or-object wire shape.

func (*PackageSource) UnmarshalJSON

func (p *PackageSource) UnmarshalJSON(data []byte) error

UnmarshalJSON preserves upstream's string-or-object wire shape.

type ParsedModelResult

type ParsedModelResult struct {
	Model         *RuntimeModel
	ThinkingLevel string
	Warning       string
}

ParsedModelResult mirrors upstream ParsedModelResult.

func ParseModelPattern

func ParseModelPattern(pattern string, availableModels []RuntimeModel, allowInvalidThinkingLevelFallback bool) ParsedModelResult

ParseModelPattern mirrors upstream parseModelPattern.

type ParsedSkillBlockFromText

type ParsedSkillBlockFromText struct {
	Name        string
	Location    string
	Content     string
	UserMessage string // trailing user text after </skill>\n\n, or ""
}

ParsedSkillBlockFromText holds the parsed skill invocation data extracted from a user message text. Mirrors upstream's ParsedSkillBlock return value from agent-session.ts:parseSkillBlock.

func ParseSkillBlock

func ParseSkillBlock(text string) *ParsedSkillBlockFromText

ParseSkillBlock attempts to parse a skill XML block from message text. Returns nil if the text doesn't match the skill block format. Mirrors upstream parseSkillBlock (agent-session.ts:102-116).

type PathMetadata

type PathMetadata struct {
	Source  string
	Scope   string
	Origin  string
	BaseDir string
}

PathMetadata is package-manager.ts PathMetadata: where a resolved resource came from.

func (PathMetadata) SourceInfo

func (m PathMetadata) SourceInfo(path string) PiSourceInfo

SourceInfo is source-info.ts createSourceInfo.

type PiSlashCommand

type PiSlashCommand struct {
	Name        string       `json:"name"`
	Description string       `json:"description,omitempty"`
	Source      string       `json:"source"`
	SourceInfo  PiSourceInfo `json:"sourceInfo"`
}

PiSlashCommand mirrors upstream SlashCommandInfo (slash-commands.ts), the entry type of pi.getCommands() and of RPC get_commands.

type PiSourceInfo

type PiSourceInfo struct {
	Path    string `json:"path"`
	Source  string `json:"source"`
	Scope   string `json:"scope"`
	Origin  string `json:"origin"`
	BaseDir string `json:"baseDir,omitempty"`
}

PiSourceInfo is upstream's SourceInfo (source-info.ts) as it travels to extensions and RPC clients: where a tool, command, template or skill came from.

func CLISourceInfo

func CLISourceInfo(path string) PiSourceInfo

CLISourceInfo is the SourceInfo upstream stamps on a resource named on the command line.

func DefaultSourceInfoForPath

func DefaultSourceInfoForPath(cwd, agentDir, filePath string) PiSourceInfo

DefaultSourceInfoForPath is resource-loader.ts getDefaultSourceInfoForPath: a path under the agent or project resource directories is local to that scope, and any other path is temporary.

func PiSourceInfoValue

func PiSourceInfoValue(value extension.SourceInfo) PiSourceInfo

PiSourceInfoValue converts an extension's opaque SourceInfo to its wire shape.

type ProcessFileOptions

type ProcessFileOptions struct {
	AutoResizeImages *bool
}

ProcessFileOptions controls CLI attachment resizing. A nil AutoResizeImages uses the upstream default, true.

type ProcessedCLIArgs

type ProcessedCLIArgs struct {
	Text   string
	Images []ai.ImageContent
}

ProcessedCLIArgs is the upstream-shaped result of processing CLI @file arguments: text placeholders plus image attachments.

func ProcessCLIFileArguments

func ProcessCLIFileArguments(fileArgs []string, cwd string, options ...ProcessFileOptions) (ProcessedCLIArgs, error)

ProcessCLIFileArguments expands CLI @file arguments into text and images. Text files use <file name="/abs/path">\ncontent\n</file>\n, including the separator when content ends in a newline. Images carry conversion or dimension hints; processing failures become omission notes. AutoResizeImages defaults to true and can be disabled until the request model is selected.

type ProjectTrustOption

type ProjectTrustOption struct {
	Label     string
	Trusted   bool
	Updates   []ProjectTrustUpdate
	SavedPath string
}

ProjectTrustOption is one row in a project-trust selector.

func GetProjectTrustOptions

func GetProjectTrustOptions(cwd string, includeSessionOnly bool) []ProjectTrustOption

GetProjectTrustOptions builds the upstream-ordered selector choices.

type ProjectTrustStore

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

ProjectTrustStore reads and writes <agentDir>/trust.json.

func NewProjectTrustStore

func NewProjectTrustStore(agentDir string) *ProjectTrustStore

NewProjectTrustStore opens the store rooted at agentDir.

func (*ProjectTrustStore) Get

func (s *ProjectTrustStore) Get(cwd string) (*bool, error)

Get returns the nearest decision for cwd, or nil when none applies.

func (*ProjectTrustStore) GetEntry

func (s *ProjectTrustStore) GetEntry(cwd string) (entry *ProjectTrustStoreEntry, err error)

GetEntry returns the nearest stored decision, walking through parent paths.

func (*ProjectTrustStore) Set

func (s *ProjectTrustStore) Set(cwd string, decision *bool) error

Set sets or clears the canonical decision for cwd.

func (*ProjectTrustStore) SetMany

func (s *ProjectTrustStore) SetMany(updates []ProjectTrustUpdate) error

SetMany applies one locked read-modify-write batch. A nil decision deletes that key; unrelated null entries already present in the store are preserved.

type ProjectTrustStoreEntry

type ProjectTrustStoreEntry struct {
	Path     string
	Decision bool
}

ProjectTrustStoreEntry is the nearest stored decision for a cwd.

type ProjectTrustUpdate

type ProjectTrustUpdate struct {
	Path     string
	Decision *bool
}

ProjectTrustUpdate sets (true/false) or clears (nil) a path's decision.

type ProjectedSessionEntry

type ProjectedSessionEntry struct {
	SourceEntry SessionEntry
	Messages    []agent.AgentMessage
}

ProjectedSessionEntry pairs a raw append-only entry with the model-visible messages it contributes after context edits (session-manager.ts ProjectedSessionEntry). Messages is empty for state-only entries and omissions.

type PromptTemplate

type PromptTemplate struct {
	Name         string // basename without .md
	Description  string // from frontmatter, or first non-empty body line truncated to 60
	ArgumentHint string // from frontmatter `argument-hint`, optional
	Content      string // body (without frontmatter)
	FilePath     string // absolute path on disk
	Scope        string // "user" | "project" | "extra"
	// SourceInfo is prompt-templates.ts PromptTemplate.sourceInfo, set by a resource loader from the resolved resource's metadata.
	SourceInfo PiSourceInfo
}

PromptTemplate is one loaded `.md` file.

type ProviderConfigInput

type ProviderConfigInput struct {
	Name         string
	BaseURL      string
	APIKey       string
	API          ai.API
	StreamSimple ai.ModelsStreamFunction
	Headers      map[string]string
	AuthHeader   *bool
	OAuth        *ExtensionOAuthConfig
	// Models are chat, image and classifier model definitions; a model without a type is a chat model.
	Models []ai.AnyModel
	// Images and Classifiers are the implementations of the image and classifier models Models declares.
	Images        ai.ProviderImageAPIMap
	Classifiers   ai.ProviderClassifierMap
	RefreshModels func(ai.RefreshModelsContext) ([]ai.AnyModel, error)
}

ProviderConfigInput is the core registration input; Models nil preserves the base catalog and an empty slice replaces it.

type ProviderRetryConfig

type ProviderRetryConfig struct {
	TimeoutMs       int
	MaxRetries      int
	MaxRetryDelayMs int
}

ProviderRetryConfig holds resolved provider/SDK retry settings.

type ProviderRetrySettings

type ProviderRetrySettings struct {
	TimeoutMs  *int `json:"timeoutMs,omitempty"`
	MaxRetries *int `json:"maxRetries,omitempty"`
	// MaxRetryDelayMs is a pointer so an explicit 0 (upstream disables the cap:
	// provider-retry.ts "set it to zero to disable the limit") is distinguishable
	// from unset (nil -> 60s default). A plain int cannot tell 0 from absent.
	MaxRetryDelayMs *int `json:"maxRetryDelayMs,omitempty"`
}

ProviderRetrySettings mirrors upstream retry.provider settings. Used for provider/SDK-level request retries and deadlines.

type QuietStartup

type QuietStartup uint8

QuietStartup mirrors upstream QuietStartup (settings-manager.ts:111-112), the union boolean | "header": true hides all startup output, "header" keeps only the startup header.

const (
	// QuietStartupFalse is false: the startup header and details show. It is the default.
	QuietStartupFalse QuietStartup = iota
	// QuietStartupTrue is true: the startup header and details are hidden.
	QuietStartupTrue
	// QuietStartupHeader is "header": the startup header shows and the details are hidden.
	QuietStartupHeader
)

func (QuietStartup) MarshalJSON

func (q QuietStartup) MarshalJSON() ([]byte, error)

MarshalJSON writes the upstream JSON value: false, true or "header".

func (QuietStartup) String

func (q QuietStartup) String() string

String returns the value as upstream's String(quietStartup) spells it: "false", "true" or "header".

func (*QuietStartup) UnmarshalJSON

func (q *QuietStartup) UnmarshalJSON(data []byte) error

UnmarshalJSON reads a settings value as upstream getQuietStartup does (settings-manager.ts:1089-1092): true and "header" keep their meaning and every other value is false.

type ReloadCellDiag

type ReloadCellDiag struct {
	Key           string
	Strategy      string
	Language      string
	Extensions    []string
	Hash          string
	BinaryPath    string
	Cached        bool
	BuildDuration time.Duration
	Replaced      bool
	Quarantined   bool
	Reason        string
}

ReloadCellDiag is a UI-safe copy of subprocess.ReloadCellReport. It is duplicated here so internal/codingagent can render /reload --explain without importing the subprocess host package directly.

type ReloadDiag

type ReloadDiag struct {
	ContextFiles int
	Skills       int
	Prompts      int
	Extensions   int
	Themes       int
	// Diagnostics is one human-readable line per warning/error gathered
	// during reload. Mirrors upstream's `[Extension issues]`,
	// `[Skill conflicts]`, `[Prompt conflicts]` sections.
	Diagnostics []string
	// Cells is the placement summary produced by the subprocess host. Empty
	// when no subprocess host is active (e.g. headless commands).
	// pig-specific. Used by /reload --explain.
	Cells []ReloadCellDiag
	// ReloadDuration is the wall time spent in subprocess Reload(). Zero when
	// the host is not active.
	ReloadDuration time.Duration
}

ReloadDiag holds resource counts and diagnostic warnings surfaced by /reload. Mirrors the information upstream showLoadedResources collects (interactive-mode.ts:1231-1410). Counts are always populated; the Diagnostics slice carries one human-readable warning line per conflict (commands, shortcuts, extension load errors).

type ReloadResourceSnapshot

type ReloadResourceSnapshot struct {
	PromptPaths  []string
	ThemePaths   []string
	SkillPaths   []string
	ContextFiles []ContextFile
	// SystemPromptSourcePaths are the system prompt files the loaded
	// resources [Context] section lists before ContextFiles.
	SystemPromptSourcePaths []string
	ResourceSourceInfo      map[string]ResourceSourceInfo
	// Err is the error resource resolution threw (an invalid settings file:
	// URL); /reload fails with it and applies nothing.
	Err error
}

ReloadResourceSnapshot is the recomputed settings/resource view used by /reload. It mirrors the upstream resource-loader/session.reload flow where prompt/theme/skill/context inputs are re-resolved from current settings.

type RequestAuthRuntime

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

RequestAuthRuntime resolves provider credentials the way upstream ModelRuntime does for request auth.

func NewRequestAuthRuntime

func NewRequestAuthRuntime(ctx context.Context, options RequestAuthRuntimeOptions) (*RequestAuthRuntime, error)

NewRequestAuthRuntime composes built-in providers with models.json.

func (*RequestAuthRuntime) CheckAuth

func (r *RequestAuthRuntime) CheckAuth(ctx context.Context, providerID string) (*ai.AuthCheck, error)

CheckAuth reports configured auth for a provider without refreshing OAuth.

func (*RequestAuthRuntime) GetAuth

func (r *RequestAuthRuntime) GetAuth(ctx context.Context, providerID string, overrides ai.AuthResolutionOverrides) (*ai.AuthResult, error)

GetAuth resolves request auth for a provider, refreshing and persisting OAuth credentials that are about to expire.

func (*RequestAuthRuntime) GetError

func (r *RequestAuthRuntime) GetError() string

GetError reports models.json, composition, and availability errors.

func (*RequestAuthRuntime) GetModelAuth

func (r *RequestAuthRuntime) GetModelAuth(ctx context.Context, model RuntimeModel, overrides ai.AuthResolutionOverrides) (*ai.AuthResult, error)

GetModelAuth resolves request auth for a model: provider auth plus the model's intrinsic and configured headers.

func (*RequestAuthRuntime) GetModels

func (r *RequestAuthRuntime) GetModels(providerID string) []RuntimeModel

GetModels returns every provider's models, or one provider's when providerID is non-empty.

func (*RequestAuthRuntime) GetProvider

func (r *RequestAuthRuntime) GetProvider(providerID string) *RuntimeProvider

GetProvider returns a composed provider by exact id, or nil.

func (*RequestAuthRuntime) GetProviders

func (r *RequestAuthRuntime) GetProviders() []*RuntimeProvider

GetProviders returns composed providers in registration order.

func (*RequestAuthRuntime) HasConfiguredAuth

func (r *RequestAuthRuntime) HasConfiguredAuth(providerID string) bool

HasConfiguredAuth reports the provider's availability from the last refresh.

func (*RequestAuthRuntime) ListCredentials

func (r *RequestAuthRuntime) ListCredentials(ctx context.Context) ([]ai.CredentialInfo, error)

ListCredentials lists stored credential metadata.

func (*RequestAuthRuntime) Refresh

func (r *RequestAuthRuntime) Refresh(ctx context.Context)

Refresh restores dynamic catalogs from the models store without network access, then recomputes configured-provider availability. An availability failure keeps the previous availability and is reported through GetError.

type RequestAuthRuntimeOptions

type RequestAuthRuntimeOptions struct {
	Credentials ai.CredentialStore
	// AgentDir holds models.json; empty means no models.json, as upstream
	// modelsPath null.
	AgentDir string
	// RefreshOnCreate computes configured-provider availability at creation.
	RefreshOnCreate bool
	// AuthContext overrides the process environment and filesystem.
	AuthContext *ai.AuthContext
	// ModelsStore holds refreshed dynamic catalogs; nil means
	// <AgentDir>/models-store.json, or an in-memory store without AgentDir.
	ModelsStore ai.ModelsStore
}

RequestAuthRuntimeOptions mirrors the CreateModelRuntimeOptions this surface honours.

type ResolveCliModelResult

type ResolveCliModelResult struct {
	Model         *RuntimeModel
	ThinkingLevel string
	Warning       string
	Error         string
}

ResolveCliModelResult carries a model selection, optional thinking suffix, warning, or CLI diagnostic.

func ResolveCliModel

func ResolveCliModel(cliProvider, cliModel, cliThinking string, runtime ModelResolverRuntime) ResolveCliModelResult

ResolveCliModel resolves explicit provider/model selections against all catalog models, not only available models. It parses a thinking suffix without applying it to a Session.

type ResolveModelScopeResult

type ResolveModelScopeResult struct {
	ScopedModels []ScopedModel
	Diagnostics  []ModelScopeDiagnostic
}

ResolveModelScopeResult preserves pattern order, first-occurrence model order, and diagnostics.

func ResolveModelScopeFromModels

func ResolveModelScopeFromModels(patterns []string, models []RuntimeModel) ResolveModelScopeResult

ResolveModelScopeFromModels resolves a scope without refreshing or reading authentication.

type ResolvedPath

type ResolvedPath struct {
	Original  string
	Canonical string
}

ResolvedPath pairs a candidate input path with its canonical path. Returned by DedupBySymlink.

func DedupBySymlink(paths []string) []ResolvedPath

DedupBySymlink returns the first input for each distinct canonical path, in input order. It follows symlinks and drive junctions but preserves Windows volume mount points as directories, as Node's realpathSync does. On resolution failure it keeps the raw path as its own canonical identity. Ports packages/coding-agent/src/core/package-manager.ts.

type ResolvedResource

type ResolvedResource struct {
	Path string
	// Enabled is false for a resource that a filter or override disabled; its metadata still applies to the path.
	Enabled  bool
	Metadata PathMetadata
}

ResolvedResource is a resolved resource path with its PathMetadata (package-manager.ts ResolvedResource).

func AmbientPromptResources

func AmbientPromptResources(cwd, agentDir string, sm *SettingsManager, project bool) []ResolvedResource

AmbientPromptResources lists the prompt templates that settings and auto-discovery yield: project entries and auto-discovery, then user entries and auto-discovery, each with the PathMetadata package-manager.ts records. The project half is skipped when project is false.

func AmbientSkillResources

func AmbientSkillResources(cwd, agentDir string, sm *SettingsManager, project, user bool) []ResolvedResource

AmbientSkillResources lists the skills that settings and auto-discovery yield, in resourcePrecedenceRank order: project settings entries, project auto-discovery, ancestor .agents/skills, user settings entries, user auto-discovery, then ~/.agents/skills, each with the PathMetadata addAutoDiscoveredResources and resolveLocalEntries record and with the enabled state the settings' patterns give it; a disabled resource is listed, not dropped (package-manager.ts:188-195, 2329-2350, 2352-2495). The project half is skipped when project is false, as project trust does upstream.

func OrderResolvedResources

func OrderResolvedResources(packages, ambient []ResolvedResource) []ResolvedResource

OrderResolvedResources is DefaultPackageManager.resolve's result for one resource type: the Packages' resources, then the settings entries (project, then user), then the auto-discovered resources fill a first-wins accumulator keyed by path, which keeps the earliest source's metadata and enabled state for a path several reach; the accumulator is stably sorted by resourcePrecedenceRank and reduced to the first resource of each canonical path (package-manager.ts:927-961, 2555-2565, 2576-2594). ambient is in AmbientSkillResources or AmbientPromptResources order.

func SkillEntryResources

func SkillEntryResources(resources []ResolvedResource) []ResolvedResource

SkillEntryResources names each skill directory resource by its SKILL.md file, as Pi's collectSkillEntries does for settings entries, auto-discovery and Package manifests (package-manager.ts:365-400, 645-653, 2317-2327, 2518-2535). PiG's resource lists name the directory; Pi's accumulator and metadataByPath key the skill by the file, so a settings entry naming the file and one naming the directory reach the same resource.

type ResourceSourceInfo

type ResourceSourceInfo struct {
	Path         string
	ResourceType string // "extensions" | "skills" | "prompts" | "themes"
	Enabled      bool
	Scope        string // "user" | "project"
	Origin       string // "package" | "top-level"
	Source       string // package source string or "local"
	BaseDir      string // package root for package-relative shortening
}

ResourceSourceInfo tracks where a loaded resource came from. Mirrors upstream PathMetadata / SourceInfo flow used by resource-loader.ts and interactive-mode.ts to annotate startup context and collision diagnostics with package origin + scope.

func ExtensionDiscoveredSourceInfo

func ExtensionDiscoveredSourceInfo(path, kind, extensionPath string) ResourceSourceInfo

ExtensionDiscoveredSourceInfo is the provenance upstream buildExtensionResourcePaths records for a resource path an extension's resources_discover handler returned: source "extension:<name>", scope "temporary", and the extension's directory as baseDir.

func (ResourceSourceInfo) DisplayName

func (i ResourceSourceInfo) DisplayName() string

DisplayName derives the path-based resource name used for collision grouping. A skill entry file uses its parent directory, matching Pi's default skill name.

type RetryConfig

type RetryConfig struct {
	Enabled     bool
	MaxRetries  int
	BaseDelayMs int
	MaxDelayMs  int
}

RetryConfig holds resolved retry settings with defaults applied.

type RetrySettingsJSON

type RetrySettingsJSON struct {
	Enabled *bool `json:"enabled,omitempty"`
	// MaxRetries and BaseDelayMs are pointers so an explicit 0 is kept, as
	// upstream's `?? default` does.
	MaxRetries  *int `json:"maxRetries,omitempty"`
	BaseDelayMs *int `json:"baseDelayMs,omitempty"`
	// MaxAgentDelayMs caps each agent-level retry delay (default 60000).
	MaxAgentDelayMs *int                   `json:"maxAgentDelayMs,omitempty"`
	Provider        *ProviderRetrySettings `json:"provider,omitempty"`
}

RetrySettingsJSON mirrors upstream Settings.retry JSON shape (settings-manager.ts:682-690). Defaults: enabled=true, maxRetries=3, baseDelayMs=2000.

type RoutedModelSelection

type RoutedModelSelection struct {
	Model         *ai.Model
	ThinkingLevel ai.ThinkingLevel
}

RoutedModelSelection is the physical model and thinking level a virtual model selection currently resolves to (AgentSession.routedModel).

type RuntimeModel

type RuntimeModel struct {
	// NativeModel retains the source model for native selection; it is not part of serialized metadata.
	NativeModel *ai.Model `json:"-"`
	Provider    string
	ID          string
	Name        string
	Reasoning   bool
	// Headers are the model's intrinsic catalog headers.
	Headers ai.ProviderHeaders
}

RuntimeModel carries the model identity, reasoning flag, and intrinsic headers used by request-auth and CLI resolution.

func FindExactModelReferenceMatch

func FindExactModelReferenceMatch(modelReference string, availableModels []RuntimeModel) *RuntimeModel

FindExactModelReferenceMatch mirrors upstream findExactModelReferenceMatch.

type RuntimeProvider

type RuntimeProvider struct {
	ID   string
	Name string
	Auth ai.ProviderAuth
	// contains filtered or unexported fields
}

RuntimeProvider carries the composed provider's identity, display name, auth methods, and model catalog.

type ScopedModel

type ScopedModel struct {
	Model         RuntimeModel
	ThinkingLevel string
}

ScopedModel pairs a model with an explicitly selected thinking level, if any.

type SelfUpdateActionResult

type SelfUpdateActionResult struct {
	Done    bool
	Action  string
	Message string
	Cause   error
}

SelfUpdateActionResult is the outcome of attempting one tier's update. The caller surfaces Action and Message verbatim; Done marks a successful mutation. Cause carries the originating error so the caller can distinguish a benign "up to date" from a real failure.

func ApplySelfUpdateTier

func ApplySelfUpdateTier(
	applyStandalone func(exePath string) error,
	applyPackageManager func(prov *SelfUpdateProvenance) error,
) SelfUpdateActionResult

ApplySelfUpdateTier resolves exactly one installation tier and applies its update, surfacing any failure from the started tier without falling through. The standalone download/replace path is supplied via applyStandalone so the cmd layer keeps ownership of the HTTP client, manifest, and version compare.

type SelfUpdateCommand

type SelfUpdateCommand struct {
	Command string
	Args    []string
	Display string
	// Steps holds an optional ordered list of commands to run in sequence.
	// Mirrors upstream SelfUpdateCommand.steps (config.ts v0.73.1).
	Steps []*SelfUpdateCommand
}

SelfUpdateCommand describes the command a proven package-manager installation runs to update itself.

Mirrors upstream SelfUpdateCommand (config.ts). Steps holds an optional sequence of sub-commands (e.g. uninstall old name, then install new name).

func PackageManagerUpdateCommand

func PackageManagerUpdateCommand(owner PackageManagerOwner, installedPackage string, npmCommand []string, target SelfUpdatePackageTarget) *SelfUpdateCommand

PackageManagerUpdateCommand returns the exact command the owning manager runs to update its installation. Mirrors upstream getSelfUpdateCommandForMethod command construction including --ignore-scripts. The owner: proven by tier resolution: drives the command name; npmCommand supplies optional extra args (e.g. a configured registry) for the npm owner only. Returns nil for an unknown owner.

type SelfUpdatePackageTarget

type SelfUpdatePackageTarget struct {
	PackageName string
	InstallSpec string
}

SelfUpdatePackageTarget is the package a self-update installs: its name, and the spec the package manager installs, which is the name when empty. Mirrors upstream SelfUpdatePackageTarget (config.ts).

type SelfUpdateProvenance

type SelfUpdateProvenance struct {
	Tier         SelfUpdateTier
	ExePath      string
	PackageOwner PackageManagerOwner
	// PackageName is the owning package spec when Tier == tierPackageManager.
	PackageName string
	// PackageDir is the owning package directory, not copied metadata below dist or a launcher directory.
	PackageDir string
	// NpmPrefix is retained only from a proven lib/node_modules root.
	NpmPrefix string
}

SelfUpdateProvenance is the resolved ownership of the running executable. Exactly one Tier is set; ambiguity is reported as an error rather than a mixed tier.

func ResolveSelfUpdateTier

func ResolveSelfUpdateTier() (*SelfUpdateProvenance, error)

ResolveSelfUpdateTier proves exactly one installation owner for the running executable before any mutation. It never mutates state. Ambiguous ownership returns a *TierError and the caller must refuse to update. Explicit npm probe failures surface unless another proven owner selects the route.

Resolution order follows the tier ladder: explicit product override (Piglet Binary baked version, or PIG_INSTALL_TIER for deployments), then package-manager ownership, then writable standalone, then read-only/Windows/ unknown remediation.

func (*SelfUpdateProvenance) GetSelfUpdateCommand

func (p *SelfUpdateProvenance) GetSelfUpdateCommand(npmCommand []string, target SelfUpdatePackageTarget) *SelfUpdateCommand

GetSelfUpdateCommand builds a command only for the proven package-manager owner. An unconfigured npm command retains the prefix of its proven lib/node_modules root.

func (*SelfUpdateProvenance) GetSelfUpdateUnavailableInstruction

func (p *SelfUpdateProvenance) GetSelfUpdateUnavailableInstruction() string

GetSelfUpdateUnavailableInstruction reports a concrete native ownership or permission failure instead of inventing an unproven package-manager command.

type SelfUpdateTier

type SelfUpdateTier string

pig divergence (D39): SelfUpdateTier selects one owner before mutation.

const (
	// TierStandalone is a writable standalone binary that pig replaces in
	// place from the configured update source.
	TierStandalone SelfUpdateTier = "standalone"
	// TierPackageManager is an installation owned by a global npm/pnpm/yarn/bun
	// install. The owning manager's exact command applies the update; pig does
	// not overwrite its file.
	TierPackageManager SelfUpdateTier = "package-manager"
	// TierImmutableBinary is a baked Piglet/Piglet Binary release. Its owning
	// release is rebuilt and re-pulled; pig does not drift the baked
	// composition in place.
	TierImmutableBinary SelfUpdateTier = "immutable-binary"
	// TierContainer is an OCI image or Piglet Image deployment. The
	// authenticated pull/redeploy path is reported; pig does not rewrite a
	// running image.
	TierContainer SelfUpdateTier = "container"
	// TierUnsupported covers read-only, Windows in-place-unsupported, and
	// unknown-provenance installations. Pig refuses mutation and reports the
	// executable path plus concrete remediation.
	TierUnsupported SelfUpdateTier = "unsupported"
)

type Session

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

Session manages a single JSONL session file. All mutations append entries; no entry is ever rewritten or deleted (the parentId/leafID dance is how branches and undo work: abandoned entries simply become orphaned subtrees in the same file).

func NewSession

func NewSession(id, cwd string, parentSession ...string) *Session

NewSession creates an in-memory session with an ISO millisecond header timestamp and an optional parent session path.

func (*Session) Accounting

func (s *Session) Accounting() SessionAccounting

func (*Session) AppendBashExecution

func (s *Session) AppendBashExecution(message BashExecutionMessage) (string, error)

AppendBashExecution persists a completed user bash message, retaining the timestamp captured before any deferred append. Returns the new entry id (the new leaf).

func (*Session) AppendBranchSummary

func (s *Session) AppendBranchSummary(parentID *string, summary string, details any, fromHook bool, usage *ai.Usage) (string, error)

AppendBranchSummary starts a new branch at parentID with a summary of the abandoned path. parentID is the explicit parent: nil means the entry is a root-level node (no parent). fromId records the leaf being abandoned ("root" when there is none). The new entry becomes the leaf.

Mirrors upstream branchWithSummary(branchFromId: string | null, ...) in session-manager.ts.

func (*Session) AppendCompaction

func (s *Session) AppendCompaction(summary, firstKeptEntryID string, tokensBefore int, details any, fromHook bool, usage *ai.Usage) (string, error)

AppendCompaction records a compaction event as a new leaf. Mirrors upstream SessionManager.appendCompaction (session-manager.ts). An empty firstKeptEntryID is Pi's null: the entry stores its own ID, so the compaction retains no preceding entries. The entry also records the current projected system state, when there is one, stamped with the entry time.

func (*Session) AppendContextEdit

func (s *Session) AppendContextEdit(targetID string, replacement *ContextEditReplacement) (string, error)

AppendContextEdit appends a branch-local edit to an earlier model-visible entry and returns the new entry ID (session-manager.ts appendContextEdit). A nil replacement omits the target. The target must be on the active branch and be a user, assistant, or tool-result message entry, or a custom_message entry. String replacements for assistant and tool-result targets are stored as one text block because those roles require content arrays.

func (*Session) AppendCustomEntry

func (s *Session) AppendCustomEntry(customType string, data any) (string, error)

AppendCustomEntry records extension-owned data with a collision-checked ID on the active branch.

func (*Session) AppendCustomMessage

func (s *Session) AppendCustomMessage(customType string, content any, display bool, details any) (string, error)

AppendCustomMessage persists an extension-injected custom message as a "custom_message" entry and returns the new entry id.

func (*Session) AppendEntry

func (s *Session) AppendEntry(entry any) error

AppendEntry appends a complete entry to memory and the session file. The caller supplies id, parentId and timestamp; a nil parent denotes a root and is never inferred from the current leaf. Returns an error if marshalling, parsing, or file write fails. Persistence errors expose Node's filesystem message while retaining the underlying Go error for errors.Is and errors.As.

func (*Session) AppendLabelChange

func (s *Session) AppendLabelChange(targetID string, label *string) error

AppendLabelChange writes a label entry for targetID. label=nil clears any existing label. Mirrors upstream appendLabelChange in session-manager.ts (line 1006).

func (*Session) AppendMessage

func (s *Session) AppendMessage(msg agent.AgentMessage) (string, error)

AppendMessage persists one upstream AgentMessage, generating a fresh entry id and timestamp and linking it to the current leaf.

func (*Session) AppendModelSwitch

func (s *Session) AppendModelSwitch(provider, modelID, displayName string) error

AppendModelSwitch persists a `model_change` audit entry recording that the user switched models mid-session. Mirrors upstream session-manager.ts:appendModelChange(provider, modelId).

func (*Session) AppendSessionInfo

func (s *Session) AppendSessionInfo(name string) (string, error)

AppendSessionInfo records a sanitized name change with a collision-checked ID on the active branch.

func (*Session) AppendSessionInfoName

func (s *Session) AppendSessionInfoName(name string) (id, current string, err error)

AppendSessionInfoName is AppendSessionInfo that also returns the name GetSessionName reports for the appended entry. Concurrent appends cannot change the returned name, so a caller publishes the name its own entry set.

func (*Session) AppendThinkingLevelChange

func (s *Session) AppendThinkingLevelChange(level string) error

AppendThinkingLevelChange persists a thinking_level_change audit entry. Mirrors upstream agentSession.appendThinkingLevelChange (agent-session.ts). Called when the user cycles the thinking level via Shift+Tab.

func (*Session) AppendUsage

func (s *Session) AppendUsage(kind, provider, model string, usage ai.Usage, note string) (UsageEntry, error)

AppendUsage appends model-attributed usage that does not participate in LLM context and returns the appended entry. Mirrors upstream SessionManager.appendUsage (session-manager.ts).

func (*Session) Branch

func (s *Session) Branch(leafID string) []SessionEntry

Branch returns the path-to-root chain (in append order: root first, leaf last) ending at leafID. Returns nil if leafID isn't an entry.

func (*Session) BuildContext

func (s *Session) BuildContext(leafID *string) []agent.AgentMessage

BuildContext returns the model-visible message list for the path ending at leafID, or at the current leaf when leafID is nil. It is the Messages field of the canonical session projection (session-manager.ts buildSessionContext), so latest compaction, retained entries, and context_edit entries on that path all apply. An unset current leaf (SetLeafID(nil)) yields no messages.

func (*Session) BuildSessionProjection

func (s *Session) BuildSessionProjection() SessionProjection

BuildSessionProjection returns the provenance-preserving projection of the current branch (session-manager.ts SessionManager.buildSessionProjection).

func (*Session) BuildSessionProjectionCalls

func (s *Session) BuildSessionProjectionCalls() int64

BuildSessionProjectionCalls returns how many times BuildSessionProjection ran, the count upstream's test reads with vi.spyOn(sessionManager, "buildSessionProjection").

func (*Session) CWD

func (s *Session) CWD() string

func (*Session) CheckSavedForFork

func (s *Session) CheckSavedForFork() error

CheckSavedForFork rejects a file-backed Session that has not been saved yet: no user or assistant message has created its file. In-memory Sessions do not require a file. Ports packages/coding-agent/src/core/agent-session-runtime.ts (fork).

func (*Session) CreateBranchedSession

func (s *Session) CreateBranchedSession(leafID string) (string, error)

CreateBranchedSession replaces this manager's active log with a new branch while retaining the manager object. A memory-only manager does not acquire a persistence path.

func (*Session) Entries

func (s *Session) Entries() []SessionEntry

Entries returns a copy of all session entries (in append order).

func (*Session) EntryByID

func (s *Session) EntryByID(id string) (SessionEntry, bool)

EntryByID looks up a session entry by its hex ID. Returns false if the ID isn't present. Used by the chat layer to render markers (e.g. branch-summary chip on fork) without exporting the byID map.

func (*Session) EntryCount

func (s *Session) EntryCount() int

EntryCount returns the number of distinct session entry IDs, excluding the header, without copying entries like Entries. A loaded file that repeats an ID counts it once. Mirrors upstream getEntryCount, which returns byId.size (session-manager.ts:1511-1513).

func (*Session) FooterUsageTotals

func (s *Session) FooterUsageTotals() footerUsageTotals

FooterUsageTotals returns the footer's all-entry usage totals without building the per-model breakdown.

func (*Session) Fork

func (s *Session) Fork(forkFromID string) error

Fork moves the leaf pointer to forkFromID so the next AppendEntry becomes a sibling branch off that point. Existing entries are not touched: abandoned tail simply becomes an orphan subtree.

Mirrors upstream `branch(id)`. Use SetLeafID(nil) for the "fork before first entry" case (root-reset).

func (*Session) GetBranch

func (s *Session) GetBranch() []SessionEntry

GetBranch returns the root-to-leaf path of the current leaf. Mirrors upstream SessionManager.getBranch() without an argument.

func (*Session) GetCwd

func (s *Session) GetCwd() string

GetCwd returns the working directory recorded by this manager.

func (*Session) GetSessionDir

func (s *Session) GetSessionDir() string

GetSessionDir returns the configured session directory. A directly loaded log without an override uses its file's parent; an in-memory manager has no directory.

func (*Session) GetSessionFile

func (s *Session) GetSessionFile() *string

GetSessionFile returns the selected persistence path, or nil for an in-memory manager. A selected file need not have been flushed yet.

func (*Session) GetSessionId

func (s *Session) GetSessionId() string

GetSessionId returns the current log identity.

func (*Session) GetSessionName

func (s *Session) GetSessionName() string

GetSessionName returns the latest user-defined session name (set via `/name`), or empty string when none has been set. Mirrors upstream `core/session-manager.ts::getSessionName` (v0.69.0:923-933): walks entries in reverse, returns the trimmed name from the most recent `session_info` entry; an empty trimmed name explicitly clears the name (later session_info entries with empty `name` field shadow earlier non-empty ones).

func (*Session) Header

func (s *Session) Header() SessionHeader

func (*Session) ID

func (s *Session) ID() string

func (*Session) IsPersisted

func (s *Session) IsPersisted() bool

IsPersisted reports whether the manager has a persistence path, independently of the first assistant-triggered flush.

func (*Session) LatestCompactionTimestampMs

func (s *Session) LatestCompactionTimestampMs() (int64, bool)

LatestCompactionTimestampMs returns the epoch-millisecond timestamp of the most recent compaction entry on the active branch (the path from the current leaf root-ward), and true when such an entry exists. Mirrors upstream getLatestCompactionEntry(getBranch()) (session-manager.ts:311), used by _checkCompaction to skip a stale pre-compaction usage reading that would otherwise re-trigger compaction on the first prompt after a resume.

func (*Session) LeafID

func (s *Session) LeafID() *string

LeafID returns the ID of the current leaf entry (the parent of the next AppendEntry). nil = "no entries yet, next append is a root".

func (*Session) NewSession

func (s *Session) NewSession(parentSession string) error

NewSession resets this manager to an empty Session with the same persistence mode and directory.

func (*Session) ParentSession

func (s *Session) ParentSession() string

func (*Session) Path

func (s *Session) Path() string

func (*Session) SetCacheReadPriceSource

func (s *Session) SetCacheReadPriceSource(prices ModelPriceSource)

SetCacheReadPriceSource binds runtime model prices during Session initialization or replacement. It rebuilds cache accounting only when historical misses need repricing; ordinary footer reads remain history-independent.

func (*Session) SetLeafID

func (s *Session) SetLeafID(id *string) error

SetLeafID moves the leaf pointer. Pass nil to reset to "before first entry" (next append becomes a new root). Returns an error if the supplied id isn't an existing entry.

func (*Session) SetPath

func (s *Session) SetPath(p string)

func (*Session) Tree

func (s *Session) Tree() *SessionTreeNode

Tree builds a SessionTreeNode rooted at the (synthetic) root. Children sorted by timestamp (oldest first). When multiple entries have parentId=nil we group them under a synthetic root with empty Entry.

func (*Session) UndecodableCount

func (s *Session) UndecodableCount() int

UndecodableCount returns how many distinct message entries failed to decode. Such entries are omitted from BuildContext, so a non-zero count means the reconstructed conversation is missing turns. Only entries already visited by messageFor are counted, so callers should read it after a full walk such as BuildContext.

type SessionAccounting

type SessionAccounting struct {
	UserMessages      int
	AssistantMessages int
	ToolCalls         int
	ToolResults       int
	TotalMessages     int
	Tokens            SessionTokenStats
	UsageBreakdown    []SessionUsageBreakdown
	CacheWaste        SessionCacheWaste
	// LatestCacheHitRate is the cache-read share (percent) of the last
	// assistant message's prompt, nil when that prompt had no tokens.
	LatestCacheHitRate *float64
}

SessionAccounting is the immutable all-entry accounting maintained with a Session.

type SessionCacheWaste

type SessionCacheWaste struct {
	MissedTokens int
	MissedCost   float64
	MissCount    int
}

SessionCacheWaste reports prompt tokens that a preceding request made cacheable but a later request did not read from cache.

type SessionContext

type SessionContext struct {
	Messages      []agent.AgentMessage `json:"messages"`
	ThinkingLevel string               `json:"thinkingLevel"`
	Model         *SessionContextModel `json:"model"`
}

SessionContext contains model-visible messages and the settings on their full branch path.

func BuildSessionContext

func BuildSessionContext(entries []SessionEntry, leafID ...*string) SessionContext

Ports packages/coding-agent/src/core/session-manager.ts (buildSessionContext). BuildSessionContext defaults to the last entry, falls back there for an unknown leaf, and treats an explicitly nil leaf as an empty branch.

type SessionContextModel

type SessionContextModel struct {
	Provider string `json:"provider"`
	ModelID  string `json:"modelId"`
}

SessionContextModel is the model identity last selected on a branch.

func GetSessionContextSettings

func GetSessionContextSettings(path []SessionEntry) (thinkingLevel string, model *SessionContextModel)

GetSessionContextSettings returns the latest model and thinking settings on a root-to-leaf path without projecting or decoding message bodies. It mirrors session-manager.ts getSessionContextSettings.

type SessionCwdIssue

type SessionCwdIssue struct {
	SessionFile string `json:"sessionFile,omitempty"`
	SessionCwd  string `json:"sessionCwd"`
	FallbackCwd string `json:"fallbackCwd"`
}

Ports packages/coding-agent/src/core/session-cwd.ts. SessionCwdIssue identifies a persisted Session whose effective working directory is missing.

func GetMissingSessionCwdIssue

func GetMissingSessionCwdIssue(session *Session, fallbackCwd string) *SessionCwdIssue

type SessionEntry

type SessionEntry struct {
	Base SessionEntryBase
	// contains filtered or unexported fields
}

SessionEntry is the union of all entry types. We keep the raw JSON alongside parsed-base fields so unknown fields survive round-trips (forward-compat: future versions of upstream may add fields we don't know about; we must not silently drop them).

func BugReportBranch

func BugReportBranch(session *Session) []SessionEntry

BugReportBranch returns the entries on the current branch.

func BuildContextEntries

func BuildContextEntries(entries []SessionEntry, leafID ...*string) []SessionEntry

BuildContextEntries returns the selected branch's compaction-aware entry list, including state-only entries.

func NewSessionEntry

func NewSessionEntry(raw json.RawMessage, base SessionEntryBase) SessionEntry

NewSessionEntry constructs a SessionEntry from raw JSON and a pre-decoded base. Used primarily by tests and external packages that need to fabricate entries.

func (SessionEntry) AsMessage

func (e SessionEntry) AsMessage() (MessageEntry, bool)

AsMessage decodes the entry as a MessageEntry. Returns (zero, false) if the entry isn't type=message.

func (SessionEntry) MarshalJSON

func (e SessionEntry) MarshalJSON() ([]byte, error)

func (SessionEntry) Raw

func (e SessionEntry) Raw() json.RawMessage

Raw returns the entry's on-disk JSON as immutable bytes.

type SessionEntryBase

type SessionEntryBase struct {
	Type      string  `json:"type"`
	ID        string  `json:"id"`
	ParentID  *string `json:"parentId"`
	Timestamp string  `json:"timestamp"`
}

SessionEntryBase is the common prefix on every non-header entry. `ParentID` is `*string` (not "") so we can distinguish "root entry" (parentId: null) from "missing field". The wire format requires `"parentId": null` literally for roots.

type SessionHeader

type SessionHeader struct {
	Type      string `json:"type"` // always "session"
	Version   int    `json:"version,omitempty"`
	ID        string `json:"id"`
	Timestamp string `json:"timestamp"`
	CWD       string `json:"cwd"`
	// ParentSession holds the absolute path of the SOURCE jsonl on a
	// clone (separate JSONL with linear path-to-leaf snapshot). Empty
	// on plain Create.
	ParentSession string `json:"parentSession,omitempty"`
}

func ReadSessionHeader

func ReadSessionHeader(path string) (*SessionHeader, error)

ReadSessionHeader scans at most Pi's header-discovery bound. Explicit opens may fall back to full loading on a scan-limit error.

type SessionHeaderScanLimitError

type SessionHeaderScanLimitError struct{ Path string }

SessionHeaderScanLimitError reports that bounded discovery could not reach a header.

func (*SessionHeaderScanLimitError) Error

func (err *SessionHeaderScanLimitError) Error() string

type SessionImportFileNotFoundError

type SessionImportFileNotFoundError struct{ FilePath string }

SessionImportFileNotFoundError reports a session import source that does not exist. Mirrors upstream SessionImportFileNotFoundError (agent-session-runtime.ts:46-54).

func (*SessionImportFileNotFoundError) Error

type SessionInfo

type SessionInfo struct {
	Path            string
	ID              string
	CWD             string
	Name            string // user-set name (via /name): empty when unset
	ParentSession   string // path of source jsonl when this session is a clone
	Created         time.Time
	Modified        time.Time
	MessageCount    int
	FirstMessage    string // first user message text: for picker preview
	AllMessagesText string // concatenated text: for fuzzy search
}

SessionInfo is the picker-display summary of a session JSONL. Returned by ListSessions; consumed by /resume picker (TUI overlay follow-up) and by --continue startup flag.

type SessionInfoEntry

type SessionInfoEntry struct {
	SessionEntryBase
	Name string `json:"name,omitempty"`
}

SessionInfoEntry stores a session-level name (set via `/name`). Persisted as type=session_info so it survives across resumes.

type SessionListOptions

type SessionListOptions struct {
	Context    context.Context
	OnProgress SessionListProgress
}

SessionListOptions supplies cancellation and progress for session discovery.

type SessionListProgress

type SessionListProgress func(loaded, total int, partial []SessionInfo)

SessionListProgress receives completed-file counts. A nil partial means no snapshot was published; a non-nil empty slice is an empty published snapshot.

type SessionManager

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

SessionManager owns the on-disk sessions directory for a given cwd and tracks the active session.

func NewSessionManager

func NewSessionManager(cwd string) *SessionManager

NewSessionManager creates a SessionManager for the given working dir.

func NewSessionManagerWithDir

func NewSessionManagerWithDir(cwd, dir string) *SessionManager

NewSessionManagerWithDir overrides the default session directory (tests use this; production callers pass the result of defaultSessionDir).

func (*SessionManager) CWD

func (sm *SessionManager) CWD() string

CWD returns the working directory.

func (*SessionManager) Clone

func (sm *SessionManager) Clone(source *Session, leafID string) (*Session, error)

Clone extracts the chosen root-to-leaf path with resolved labels into a fresh Session. In-memory sessions stay in memory. A persisted clone is written immediately only when its path contains a user or assistant message; otherwise its first such message creates the file.

func (*SessionManager) Create

func (sm *SessionManager) Create(id, parentSessionPath string) (*Session, error)

Create validates a supplied session ID or generates an omitted one, then assigns the deferred session file path. parentSessionPath records a source session when supplied.

func (*SessionManager) Current

func (sm *SessionManager) Current() *Session

Current returns the active session.

func (*SessionManager) DeleteSession

func (sm *SessionManager) DeleteSession(path string) error

DeleteSession deletes a session file within the listed root, trying trash before unlink. A file that is already gone counts as success, as in the selector.

func (*SessionManager) FindByID

func (sm *SessionManager) FindByID(id string) string

FindByID finds an exact header ID without reading transcript bodies. A custom session directory is filtered by cwd; discovery errors are best-effort.

func (*SessionManager) FindMostRecent

func (sm *SessionManager) FindMostRecent() string

FindMostRecent returns the path to the most-recently-modified valid session jsonl in this manager's directory, or "" when none exist.

func (*SessionManager) FindMostRecentForContinue

func (sm *SessionManager) FindMostRecentForContinue() string

FindMostRecentForContinue selects the session to resume for the `--continue` flag, mirroring upstream `SessionManager.continueRecent` (session-manager.ts). When this manager's directory is the cwd-encoded default it holds only this cwd's sessions, so the newest wins outright. When it is a custom `--session-dir` that may be shared across projects, the result is filtered to the newest session whose header cwd refers to this cwd (upstream's `filterCwd` branch) so `--continue` never resumes another project's session.

func (*SessionManager) ForkFromFile

func (sm *SessionManager) ForkFromFile(sourcePath string, idOption ...string) (*Session, error)

ForkFromFile copies every non-header entry from sourcePath into a new JSONL. An optional ID is validated and used verbatim; omission generates a UUIDv7. The header records the absolute source path as parentSession. Unlike Clone, this preserves the complete entry tree and writes the file immediately.

func (*SessionManager) ForkToNewSession

func (sm *SessionManager) ForkToNewSession(source *Session, userMsgEntryID string) (*Session, string, error)

ForkToNewSession creates a NEW session file branched at the PARENT of userMsgEntryID (so the selected user message itself is excluded) and switches sm's current session to it. It returns the new session and the selected message's text, which the caller prefills into the editor for modification. Mirrors upstream AgentSessionRuntime.fork() with the default position "before": createBranchedSession(selectedEntry.parentId), or a fresh session carrying `parentSession` when the selected message is the root.

func (*SessionManager) ListAllSessions

func (sm *SessionManager) ListAllSessions(options ...SessionListOptions) ([]SessionInfo, error)

ListAllSessions returns every valid session JSONL under <agentDir>/sessions/*/*.jsonl, newest message activity first. Mirrors upstream session selector "All" scope.

func (*SessionManager) ListCurrentSessions

func (sm *SessionManager) ListCurrentSessions(options ...SessionListOptions) ([]SessionInfo, error)

ListCurrentSessions returns the selector's Current Folder scope. A custom session directory may contain sessions from several projects, so it filters by header cwd; the default encoded directory is already cwd-scoped.

func (*SessionManager) ListSessions

func (sm *SessionManager) ListSessions(options ...SessionListOptions) ([]SessionInfo, error)

ListSessions returns every valid jsonl in this manager's session directory, newest message activity first. Files that fail header parsing are silently skipped (matches upstream: corrupted sessions shouldn't crash the picker).

func (*SessionManager) Load

func (sm *SessionManager) Load(path string) (*Session, error)

Load reads and migrates a session JSONL and makes it current. A missing path starts a fresh session at that exact path, with persistence deferred until the first user or assistant message.

func (*SessionManager) Open

func (sm *SessionManager) Open(path string, cwdOverride ...string) (*Session, error)

Open opens an explicit session file, with an optional effective working-directory override.

func (*SessionManager) RenameSession

func (sm *SessionManager) RenameSession(path, newName string) error

RenameSession updates the session name by appending a session_info entry. Mirrors upstream session-selector.ts rename functionality.

func (*SessionManager) SessionDir

func (sm *SessionManager) SessionDir() string

SessionDir returns the session directory.

type SessionProjection

type SessionProjection struct {
	Entries  []ProjectedSessionEntry
	Messages []agent.AgentMessage
}

SessionProjection is the provenance-preserving, compaction-aware model context of one branch (session-manager.ts SessionProjection).

func BuildSessionProjection

func BuildSessionProjection(pathEntries []SessionEntry) SessionProjection

BuildSessionProjection projects a root-to-leaf entry path (session-manager.ts buildSessionProjection with the path's final entry as leaf). Compaction preparation uses it on SessionManager.getBranch() output.

type SessionTokenStats

type SessionTokenStats struct {
	Input      int
	Output     int
	CacheRead  int
	CacheWrite int
	Total      int
	Cost       float64 // USD; only shown if > 0
}

SessionTokenStats holds token usage for the /session display. Mirrors upstream SessionStats.tokens (agent-session.ts:2913-2918).

type SessionTreeNode

type SessionTreeNode struct {
	Entry    SessionEntry
	Children []*SessionTreeNode
	Label    string
	// LabelTimestamp is the on-disk timestamp of the LabelEntry that
	// set Label, in upstream's ISO-8601-ish wire format. Empty when
	// no label is set. Used by the /tree picker to render `hh:mm`
	// next to the label when the user toggles label timestamps on
	// (mirrors upstream tree-selector.ts:678-682).
	LabelTimestamp string
}

SessionTreeNode is a defensive copy of the session's branch structure for the /tree overlay (follow-up).

type SessionUsageBreakdown

type SessionUsageBreakdown struct {
	Key    string
	Cost   float64
	Tokens int
}

SessionUsageBreakdown attributes billed usage to a model or to host-side summaries.

type Settings

type Settings struct {
	DefaultProvider      string `json:"defaultProvider,omitempty"`
	DefaultModel         string `json:"defaultModel,omitempty"`
	DefaultThinkingLevel string `json:"defaultThinkingLevel,omitempty"`
	// HideThinkingBlock mirrors upstream settings.hideThinkingBlock
	// (settings-manager.ts:77). When true, thinking blocks show as
	// "Thinking..." stubs instead of the full reasoning trace. Toggled
	// by Ctrl+T; persisted so the preference survives sessions.
	HideThinkingBlock bool `json:"hideThinkingBlock,omitempty"`

	// Theme is the configured name. JSON and SettingsManager.SetTheme preserve explicitly empty values.
	Theme string `json:"theme,omitempty"`

	ShellPath string `json:"shellPath,omitempty"`
	// CommandPrefix prepended to every bash tool invocation as a
	// separate first line (e.g. "set -e\n" or "export PATH=...\n").
	CommandPrefix string       `json:"commandPrefix,omitempty"`
	QuietStartup  QuietStartup `json:"quietStartup,omitempty"`

	Packages                  []PackageSource `json:"packages,omitzero"`
	Extensions                []string        `json:"extensions,omitempty"`
	Skills                    []string        `json:"skills,omitempty"`
	Prompts                   []string        `json:"prompts,omitempty"`
	Themes                    []string        `json:"themes,omitempty"`
	SessionDir                string          `json:"sessionDir,omitempty"`
	HTTPProxy                 string          `json:"httpProxy,omitempty"`
	WebSocketConnectTimeoutMs *int            `json:"websocketConnectTimeoutMs,omitempty"`

	HTTPIdleTimeoutMs *int     `json:"httpIdleTimeoutMs,omitempty"`
	EnabledModels     []string `json:"enabledModels,omitempty"`
	// DefaultTools is the initial built-in tool selection; nil means the
	// upstream default read, bash, edit and write.
	DefaultTools []string `json:"defaultTools,omitempty"`
	// ModelThinkingLevels holds per-model default thinking levels keyed by
	// "provider/modelId".
	ModelThinkingLevels map[string]string `json:"modelThinkingLevels,omitempty"`

	// CacheWarming is read from global settings only, because each refresh
	// costs money. Mirrors upstream settings.cacheWarming.
	CacheWarming CacheWarmingMode `json:"cacheWarming,omitempty"`

	// LastChangelogVersion records the binary version at which the
	// user last saw the startup changelog notification. Used to gate
	// "what's new" display to only new entries since last run.
	// Mirrors upstream settings.lastChangelogVersion (settings-manager.ts:66).
	LastChangelogVersion string `json:"lastChangelogVersion,omitempty"`

	// Compaction mirrors upstream settings.compaction (settings-manager.ts:74).
	// Nested to match upstream JSON schema:
	// { "compaction": { "enabled": true, "reserveTokens": 16384, "keepRecentTokens": 20000 } }
	Compaction *CompactionSettingsJSON `json:"compaction,omitempty"`

	// BranchSummary mirrors upstream settings.branchSummary
	// (settings-manager.ts:75). Nested to match upstream JSON schema:
	// { "branchSummary": { "skipPrompt": true, "reserveTokens": 16384 } }
	BranchSummary *BranchSummaryConfig `json:"branchSummary,omitempty"`

	// DoubleEscapeAction controls what double-Esc with empty editor does.
	// Values: "fork", "tree", "none". Default: "tree".
	// Mirrors upstream settings.doubleEscapeAction (settings-manager.ts:93).
	DoubleEscapeAction string `json:"doubleEscapeAction,omitempty"`

	// TreeFilterMode controls the default /tree filter.
	// Values: "default", "no-tools", "user-only", "labeled-only", "all".
	// Default: "default".
	// Mirrors upstream settings.treeFilterMode (settings-manager.ts:94).
	TreeFilterMode string `json:"treeFilterMode,omitempty"`

	// DefaultProjectTrust is the fallback when no extension or saved decision
	// resolves project trust. Values: "ask" | "always" | "never". Default: "ask".
	// Global setting only. Mirrors upstream settings.defaultProjectTrust
	// (settings-manager.ts:94).
	DefaultProjectTrust string `json:"defaultProjectTrust,omitempty"`

	// SteeringMode controls queue dispatch when multiple messages are queued.
	// Values: "all" | "one-at-a-time". Default: "one-at-a-time".
	// Mirrors upstream settings.steeringMode (settings-manager.ts:71).
	SteeringMode string `json:"steeringMode,omitempty"`

	// FollowUpMode controls how queued follow-up messages are dispatched.
	// Values: "all" | "one-at-a-time". Default: "one-at-a-time".
	// Mirrors upstream settings.followUpMode (settings-manager.ts:72).
	FollowUpMode string `json:"followUpMode,omitempty"`

	// TuiMode selects the regular or fullscreen terminal layout. Default: fullscreen.
	TuiMode string `json:"tuiMode,omitempty"`

	// FullscreenExitOutput controls whether fullscreen exit prints the transcript
	// or restores the previous screen. Values: transcript, resume-hint. Default: transcript.
	FullscreenExitOutput string `json:"fullscreenExitOutput,omitempty"`

	// FullscreenScrollbar controls fullscreen scrollbars. Values: auto, always,
	// hidden. Default: auto; it has no effect in regular mode.
	FullscreenScrollbar string `json:"fullscreenScrollbar,omitempty"`

	// FullscreenCopyOnSelect controls automatic clipboard copy when a fullscreen
	// text selection completes. Default: true; it has no effect in regular mode.
	FullscreenCopyOnSelect *bool `json:"fullscreenCopyOnSelect,omitempty"`

	// FullscreenWheelScrollLines holds the authored `fullscreenWheelScrollLines` JSON value, a line count or "auto". GetFullscreenWheelScrollLines validates it. A present JSON null is kept because it overrides a lower layer.
	FullscreenWheelScrollLines json.RawMessage `json:"fullscreenWheelScrollLines,omitempty"`

	// DeviceID is the stable UUID of this installation. Only the global layer is read for it: GetOrCreateDeviceID ignores project settings.
	// Mirrors upstream settings.deviceId (settings-manager.ts:156).
	DeviceID string `json:"deviceId,omitempty"`

	// Codemode configures how the codemode tool presents tools. Mirrors upstream settings.codemode (settings-manager.ts:176).
	Codemode *CodemodeSettings `json:"codemode,omitempty"`

	// MaskSecretInput controls configurable login-input privacy. Nil means true; false restores Pi's plain-text prompts.
	MaskSecretInput *bool `json:"maskSecretInput,omitempty"`

	// CollapseChangelog shows condensed startup update notices. The /changelog command always shows every released entry.
	CollapseChangelog bool `json:"collapseChangelog,omitempty"`

	// ShowCacheMissNotices controls transcript notices for significant prompt
	// cache misses. Default: false. Mirrors upstream settings.showCacheMissNotices
	// (settings-manager.ts:96).
	ShowCacheMissNotices bool `json:"showCacheMissNotices,omitempty"`

	// EnableSkillCommands, when false, hides skill commands from the
	// /skill:name autocomplete popup. Default: true.
	// Mirrors upstream settings.enableSkillCommands (settings-manager.ts:89).
	// Note: this is a *bool so false can explicitly disable (vs absent=true default).
	// Use GetEnableSkillCommands() instead of reading directly.
	EnableSkillCommands *bool `json:"enableSkillCommands,omitempty"`

	// EnableInstallTelemetry controls whether package-install telemetry may be sent
	// by pig-specific install telemetry hooks when they are configured.
	// Default: true.
	// Mirrors upstream settings.enableInstallTelemetry (settings-manager.ts), but
	// the transport itself is a separate implementation concern.
	EnableInstallTelemetry *bool `json:"enableInstallTelemetry,omitempty"`

	// EnableAnalytics is the opt-in analytics data sharing setting (default
	// false). Mirrors upstream settings plumbing only: nothing sends data.
	EnableAnalytics *bool `json:"enableAnalytics,omitempty"`
	// TrackingID is the analytics tracking identifier generated on the first
	// opt-in. Bug reports strip it.
	TrackingID string `json:"trackingId,omitempty"`

	// Retry mirrors upstream settings.retry (settings-manager.ts:682-690).
	// Nested JSON: { "retry": { "enabled": true, "maxRetries": 2,
	//   "baseDelayMs": 10000, "maxDelayMs": 60000 } }
	Retry *RetrySettingsJSON `json:"retry,omitempty"`

	// ShowImages controls whether inline images are rendered in tool results
	// and assistant messages. Default: true.
	// Mirrors upstream settings.showImages (settings-manager.ts:84).
	ShowImages *bool `json:"showImages,omitempty"`

	// ImageWidthCells is the max width (in terminal columns) for inline images.
	// Default: 60. Mirrors upstream settings.imageWidthCells (settings-manager.ts:85).
	ImageWidthCells int `json:"imageWidthCells,omitempty"`

	// BlockImages, when true, blocks image rendering entirely. Default: false.
	// Mirrors upstream settings.blockImages (settings-manager.ts:86).
	BlockImages bool `json:"blockImages,omitempty"`

	// ImageAutoResize, when true, automatically resizes images to fit the
	// terminal width. Default: true.
	// Mirrors upstream settings.imageAutoResize (settings-manager.ts:87).
	ImageAutoResize *bool `json:"imageAutoResize,omitempty"`

	// Transport controls HTTP transport behavior.
	// Values: "sse" | "websocket" | "websocket-cached" | "auto". Default: "auto".
	// Mirrors upstream settings.transport (settings-manager.ts:70).
	Transport string `json:"transport,omitempty"`

	// ShowHardwareCursor controls whether the hardware cursor is shown.
	// Default: false (or PI_HARDWARE_CURSOR=1 env).
	// Mirrors upstream settings.showHardwareCursor (settings-manager.ts:944).
	ShowHardwareCursor *bool `json:"showHardwareCursor,omitempty"`

	// EditorPaddingX is horizontal padding (in cells) for the editor.
	// Range: 0-3. Default: 0.
	// Mirrors upstream settings.editorPaddingX (settings-manager.ts:951).
	EditorPaddingX *int `json:"editorPaddingX,omitempty"`

	// OutputPad is horizontal padding (in cells) for chat output.
	// Range: 0-1. Default: 1.
	// Mirrors upstream settings.outputPad (settings-manager.ts:116).
	OutputPad *int `json:"outputPad,omitempty"`

	// ExternalEditor is the command Ctrl+G uses before VISUAL/EDITOR fallbacks.
	// Mirrors upstream settings.externalEditor (settings-manager.ts:93).
	ExternalEditor string `json:"externalEditor,omitempty"`

	// AutocompleteMaxVisible is the max number of autocomplete suggestions shown.
	// Range: 3-20. Default: 5.
	// Mirrors upstream settings.autocompleteMaxVisible (settings-manager.ts:958).
	AutocompleteMaxVisible *int `json:"autocompleteMaxVisible,omitempty"`

	// ClearOnShrink controls whether the screen is cleared when terminal shrinks.
	// Default: false.
	// Mirrors upstream settings.clearOnShrink (settings-manager.ts:891).
	ClearOnShrink *bool `json:"clearOnShrink,omitempty"`

	// ShowTerminalProgress controls OSC 9;4 terminal progress indicators.
	// Default: false.
	ShowTerminalProgress *bool `json:"showTerminalProgress,omitempty"`

	// ThinkingBudgets controls per-level token budgets for extended thinking.
	// Mirrors upstream settings.thinkingBudgets (settings-manager.ts:857).
	ThinkingBudgets *ThinkingBudgetsSettings `json:"thinkingBudgets,omitempty"`

	// NpmCommand overrides the npm command used for package operations.
	// Default: ["npm"].
	// Mirrors upstream settings.npmCommand (settings-manager.ts:830).
	NpmCommand []string `json:"npmCommand,omitempty"`

	// Markdown holds markdown rendering settings.
	// Mirrors upstream settings.markdown (settings-manager.ts:965).
	Markdown *MarkdownSettings `json:"markdown,omitempty"`

	// Warnings holds persisted warning-dismissal preferences.
	Warnings *WarningSettings `json:"warnings,omitempty"`
	// contains filtered or unexported fields
}

Settings mirrors upstream Settings interface.

func ThemeOverride

func ThemeOverride(theme string) Settings

ThemeOverride returns ApplyOverrides input that selects theme, as Pi's applyOverrides({theme}). An empty name is a selection, not an omitted key.

func (Settings) GetAutocompleteMaxVisible

func (s Settings) GetAutocompleteMaxVisible() int

GetAutocompleteMaxVisible returns max autocomplete items. Default: 5.

func (Settings) GetBlockImages

func (s Settings) GetBlockImages() bool

GetBlockImages returns whether image rendering is blocked entirely.

func (Settings) GetClearOnShrink

func (s Settings) GetClearOnShrink() bool

GetClearOnShrink returns whether screen clears on terminal shrink. Default: false.

func (Settings) GetCodeBlockIndent

func (s Settings) GetCodeBlockIndent() string

GetCodeBlockIndent returns the markdown code block indent string. Default: " ".

func (Settings) GetCollapseChangelog

func (s Settings) GetCollapseChangelog() bool

GetCollapseChangelog returns whether changelog output is collapsed.

func (Settings) GetCommandPrefix

func (s Settings) GetCommandPrefix() string

func (Settings) GetDefaultTools

func (s Settings) GetDefaultTools() []string

GetDefaultTools returns the resolved `defaultTools` selection, or nil when no settings layer sets it: plain names replace the built-in defaults, then `+name` and `-name` entries apply in order. Mirrors upstream getDefaultTools (settings-manager.ts:1430-1434).

func (Settings) GetEditorPaddingX

func (s Settings) GetEditorPaddingX() int

GetEditorPaddingX returns horizontal editor padding. Default: 0.

func (Settings) GetHideThinkingBlock

func (s Settings) GetHideThinkingBlock() bool

GetHideThinkingBlock returns whether thinking blocks should be hidden.

func (Settings) GetImageAutoResize

func (s Settings) GetImageAutoResize() bool

GetImageAutoResize returns whether images should auto-resize. Default true.

func (Settings) GetImageWidthCells

func (s Settings) GetImageWidthCells() int

GetImageWidthCells returns the max image width in columns. Default 60.

func (Settings) GetMaskSecretInput

func (s Settings) GetMaskSecretInput() bool

GetMaskSecretInput returns the login-input privacy setting, enabled by default.

func (Settings) GetOutputPad

func (s Settings) GetOutputPad() int

GetOutputPad returns zero only for an explicit zero setting, and one otherwise.

func (Settings) GetQuietStartup

func (s Settings) GetQuietStartup() QuietStartup

GetQuietStartup returns the quiet startup setting: true, "header" or false.

func (Settings) GetShellPath

func (s Settings) GetShellPath() (string, error)

GetShellPath satisfies tools.SettingsView so the bash tool can resolve the user's preferred shell without importing internal/codingagent (which would create a cycle).

func (Settings) GetShowCacheMissNotices

func (s Settings) GetShowCacheMissNotices() bool

GetShowCacheMissNotices returns whether transcript cache-miss notices are shown.

func (Settings) GetShowHardwareCursor

func (s Settings) GetShowHardwareCursor() bool

GetShowHardwareCursor returns whether the hardware cursor is shown. Default: false (or PI_HARDWARE_CURSOR=1 env).

func (Settings) GetShowImages

func (s Settings) GetShowImages() bool

GetShowImages returns whether inline images should be rendered. Default true.

func (Settings) GetShowTerminalProgress

func (s Settings) GetShowTerminalProgress() bool

GetShowTerminalProgress returns whether OSC 9;4 terminal progress indicators are enabled.

func (Settings) GetTerminalCapabilityOverrides

func (s Settings) GetTerminalCapabilityOverrides() tui.CapabilityOverrides

GetTerminalCapabilityOverrides mirrors upstream SettingsManager.getTerminalCapabilityOverrides: terminal.images "kitty" or "iterm2" selects that protocol and false disables images; a boolean terminal.trueColor or terminal.hyperlinks overrides detection. "auto" and any other value leave detection alone.

func (Settings) MarshalJSON

func (s Settings) MarshalJSON() ([]byte, error)

MarshalJSON emits upstream's settings wire shape while preserving pig's internal flattened representation.

func (*Settings) UnmarshalJSON

func (s *Settings) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts upstream's settings wire shape and legacy pig flat aliases for backward compatibility.

type SettingsError

type SettingsError struct {
	Scope string
	// Path is the settings file behind the error. Mirrors upstream
	// SettingsError.path, which file-backed storage always sets.
	Path  string
	Error error
}

SettingsError mirrors upstream settings-manager.ts load/write diagnostics.

type SettingsManager

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

SettingsManager loads and merges settings from global and project scopes. Merge order: global defaults → project → CLI flags.

func NewInMemorySettingsManager

func NewInMemorySettingsManager(settings Settings) *SettingsManager

NewInMemorySettingsManager creates an independent settings manager without file I/O. Ports packages/coding-agent/src/core/settings-manager.ts:403-410.

func NewSettingsManager

func NewSettingsManager(cwd, agentDir string) *SettingsManager

NewSettingsManager creates a SettingsManager for the given directories.

func NewSettingsManagerWithProjectTrust

func NewSettingsManagerWithProjectTrust(cwd, agentDir string, projectTrusted bool) *SettingsManager

NewSettingsManagerWithProjectTrust creates a settings manager that reads project settings only when projectTrusted is true.

func (*SettingsManager) AgentDir

func (sm *SettingsManager) AgentDir() string

AgentDir returns the global settings directory backing this manager.

func (*SettingsManager) ApplyOverrides

func (sm *SettingsManager) ApplyOverrides(overrides Settings)

ApplyOverrides applies non-persistent overrides on top of the merged settings. Mirrors upstream SettingsManager.applyOverrides.

func (*SettingsManager) CWD

func (sm *SettingsManager) CWD() string

CWD returns the project directory backing this manager.

func (*SettingsManager) DrainErrors

func (sm *SettingsManager) DrainErrors() []SettingsError

DrainErrors returns accumulated load/write diagnostics, or an empty list, and clears them.

func (*SettingsManager) ExtensionSettings

func (sm *SettingsManager) ExtensionSettings() extension.Settings

ExtensionSettings is GetSettings as the JSON object extensions read: a copy that a change does not reach back into the manager through.

upstream: settings-manager.ts:562-564 (getSettings), loader.ts:411-414

func (*SettingsManager) Flush

func (sm *SettingsManager) Flush() error

Flush waits for queued writes. pig writes settings synchronously, so this is a no-op. Mirrors upstream SettingsManager.flush() API for parity.

func (*SettingsManager) Get

func (sm *SettingsManager) Get() Settings

Get returns the merged settings.

func (*SettingsManager) GetAutocompleteMaxVisible

func (sm *SettingsManager) GetAutocompleteMaxVisible() int

GetAutocompleteMaxVisible returns max autocomplete items visible.

func (*SettingsManager) GetBlockImages

func (sm *SettingsManager) GetBlockImages() bool

GetBlockImages returns whether image rendering is blocked entirely.

func (*SettingsManager) GetBranchSummarySettings

func (sm *SettingsManager) GetBranchSummarySettings() BranchSummaryConfig

GetBranchSummarySettings returns branch summary settings, applying any reserve-token override from the merged settings. Mirrors upstream SettingsManager.getBranchSummarySettings (settings-manager.ts).

func (*SettingsManager) GetBranchSummarySkipPrompt

func (sm *SettingsManager) GetBranchSummarySkipPrompt() bool

GetBranchSummarySkipPrompt returns whether branch-summary prompt skipping is enabled.

func (*SettingsManager) GetCacheWarmingMode

func (sm *SettingsManager) GetCacheWarmingMode() CacheWarmingMode

GetCacheWarmingMode returns the global cache-warming mode, or "streaming" when it is unset or invalid. Project settings are ignored because each refresh costs money. Mirrors upstream getCacheWarmingMode.

func (*SettingsManager) GetClearOnShrink

func (sm *SettingsManager) GetClearOnShrink() bool

GetClearOnShrink returns whether screen clears on terminal shrink.

func (*SettingsManager) GetCodeBlockIndent

func (sm *SettingsManager) GetCodeBlockIndent() string

GetCodeBlockIndent returns the markdown code block indent string.

func (*SettingsManager) GetCollapseChangelog

func (sm *SettingsManager) GetCollapseChangelog() bool

GetCollapseChangelog returns whether to show a condensed changelog. Default: false. Mirrors upstream getCollapseChangelog (settings-manager.ts:743).

func (*SettingsManager) GetCompactionEnabled

func (sm *SettingsManager) GetCompactionEnabled() bool

GetCompactionEnabled returns the global compaction toggle independently of model token validation.

func (*SettingsManager) GetCompactionKeepRecentTokens

func (sm *SettingsManager) GetCompactionKeepRecentTokens(model ...string) (int, error)

GetCompactionKeepRecentTokens resolves and validates the retention setting. The optional model is a provider/model-ID pair.

func (*SettingsManager) GetCompactionReserveTokens

func (sm *SettingsManager) GetCompactionReserveTokens(model ...string) (int, error)

GetCompactionReserveTokens resolves and validates the reserve token setting. The optional model is a provider/model-ID pair.

func (*SettingsManager) GetCompactionSettings

func (sm *SettingsManager) GetCompactionSettings() (CompactionConfig, error)

GetCompactionSettings resolves ordinary settings and rejects invalid authored token values.

func (*SettingsManager) GetDefaultModel

func (sm *SettingsManager) GetDefaultModel() string

GetDefaultModel returns the configured default model, or "".

func (*SettingsManager) GetDefaultProjectTrust

func (sm *SettingsManager) GetDefaultProjectTrust() string

GetDefaultProjectTrust returns the fallback project-trust mode. Values: "ask" | "always" | "never". Default: "ask".

func (*SettingsManager) GetDefaultProvider

func (sm *SettingsManager) GetDefaultProvider() string

GetDefaultProvider returns the configured default provider, or "".

func (*SettingsManager) GetDefaultThinkingLevel

func (sm *SettingsManager) GetDefaultThinkingLevel() string

GetDefaultThinkingLevel returns the configured thinking level, or "".

func (*SettingsManager) GetDefaultTools

func (sm *SettingsManager) GetDefaultTools() []string

GetDefaultTools returns the configured initial built-in tool selection, or nil. Mirrors upstream SettingsManager.getDefaultTools.

func (*SettingsManager) GetDoubleEscapeAction

func (sm *SettingsManager) GetDoubleEscapeAction() string

GetDoubleEscapeAction returns the double-escape action setting. Default: "tree". Mirrors upstream SettingsManager.getDoubleEscapeAction (settings-manager.ts:944-946).

func (*SettingsManager) GetEditorPaddingX

func (sm *SettingsManager) GetEditorPaddingX() int

GetEditorPaddingX returns horizontal editor padding.

func (*SettingsManager) GetEnableAnalytics

func (sm *SettingsManager) GetEnableAnalytics() bool

GetEnableAnalytics reports the opt-in analytics setting (default false). Mirrors upstream SettingsManager.getEnableAnalytics.

func (*SettingsManager) GetEnableInstallTelemetry

func (sm *SettingsManager) GetEnableInstallTelemetry() bool

GetEnableInstallTelemetry returns whether package-install telemetry is enabled. Default: true. This only answers the setting/env gate; it does not imply a transport is configured or that telemetry will actually be delivered.

func (*SettingsManager) GetEnableSkillCommands

func (sm *SettingsManager) GetEnableSkillCommands() bool

GetEnableSkillCommands returns whether skill commands are shown in autocomplete. Default: true. Mirrors upstream getEnableSkillCommands (settings-manager.ts:1264-1266).

func (*SettingsManager) GetEnabledModels

func (sm *SettingsManager) GetEnabledModels() []string

GetEnabledModels returns the list of enabled models for Ctrl+P cycling, or nil.

func (*SettingsManager) GetExtensionPaths

func (sm *SettingsManager) GetExtensionPaths() []string

GetExtensionPaths returns the configured extension paths, or an empty list.

func (*SettingsManager) GetExternalEditorCommand

func (sm *SettingsManager) GetExternalEditorCommand() string

GetExternalEditorCommand resolves a nonblank configured command, VISUAL, EDITOR, then the platform default, without trimming the selected command.

func (*SettingsManager) GetFollowUpMode

func (sm *SettingsManager) GetFollowUpMode() string

GetFollowUpMode returns the follow-up queue dispatch mode. Default: "one-at-a-time". Mirrors upstream getFollowUpMode (settings-manager.ts:591).

func (*SettingsManager) GetFullscreenCopyOnSelect

func (sm *SettingsManager) GetFullscreenCopyOnSelect() bool

func (*SettingsManager) GetFullscreenExitOutput

func (sm *SettingsManager) GetFullscreenExitOutput() string

func (*SettingsManager) GetFullscreenScrollbar

func (sm *SettingsManager) GetFullscreenScrollbar() string

func (*SettingsManager) GetFullscreenWheelScrollLines

func (sm *SettingsManager) GetFullscreenWheelScrollLines() WheelScrollLines

GetFullscreenWheelScrollLines returns the wheel line setting: a finite number floored and clamped to 1-100, otherwise auto. Mirrors upstream getFullscreenWheelScrollLines (settings-manager.ts:1386-1391).

func (*SettingsManager) GetGlobalSettings

func (sm *SettingsManager) GetGlobalSettings() Settings

GetGlobalSettings returns the persisted global settings layer.

func (*SettingsManager) GetHideThinkingBlock

func (sm *SettingsManager) GetHideThinkingBlock() bool

GetHideThinkingBlock returns whether thinking blocks should be hidden.

func (*SettingsManager) GetHttpIdleTimeoutMs

func (sm *SettingsManager) GetHttpIdleTimeoutMs() (int, error)

GetHttpIdleTimeoutMs returns the HTTP header/body idle timeout in milliseconds. Default: 300000 (5 minutes). Zero disables the timeout. An unparseable value is an error, as upstream parseTimeoutSetting throws.

func (*SettingsManager) GetImageAutoResize

func (sm *SettingsManager) GetImageAutoResize() bool

GetImageAutoResize returns whether images auto-resize.

func (*SettingsManager) GetImageWidthCells

func (sm *SettingsManager) GetImageWidthCells() int

GetImageWidthCells returns the max image width in columns.

func (*SettingsManager) GetLastChangelogVersion

func (sm *SettingsManager) GetLastChangelogVersion() string

GetLastChangelogVersion returns the last seen changelog version string. Mirrors upstream getLastChangelogVersion (settings-manager.ts:529).

func (*SettingsManager) GetMermaidRenderingMode

func (sm *SettingsManager) GetMermaidRenderingMode() string

func (*SettingsManager) GetModelCompactionSettings

func (sm *SettingsManager) GetModelCompactionSettings(provider, modelID string) (CompactionConfig, error)

GetModelCompactionSettings resolves each token field through the exact model override, ordinary setting, and built-in default. Ordinary values are validated before their overrides.

func (*SettingsManager) GetModelThinkingLevel

func (sm *SettingsManager) GetModelThinkingLevel(provider, modelID string) string

GetModelThinkingLevel returns the per-model default thinking level for provider/modelID, or "". Mirrors upstream getModelThinkingLevel.

func (*SettingsManager) GetNpmCommand

func (sm *SettingsManager) GetNpmCommand() []string

GetNpmCommand returns the npm command override. Default: nil (use "npm").

func (*SettingsManager) GetOrCreateDeviceID

func (sm *SettingsManager) GetOrCreateDeviceID() string

GetOrCreateDeviceID returns the stable ID of this installation, e.g. sent to OpenAI as its agent host ID, and creates it on first use. Project settings are ignored so a committed project settings file cannot give every clone the same ID. A global file that does not parse keeps the new ID in memory only, as upstream's save() returns before writing then. Mirrors upstream getOrCreateDeviceId (settings-manager.ts:1172-1179).

func (*SettingsManager) GetOutputPad

func (sm *SettingsManager) GetOutputPad() int

GetOutputPad returns horizontal chat output padding.

func (*SettingsManager) GetPackages

func (sm *SettingsManager) GetPackages() []PackageSource

GetPackages returns the configured package sources, or an empty list.

func (*SettingsManager) GetProjectSettings

func (sm *SettingsManager) GetProjectSettings() Settings

GetProjectSettings returns the persisted project settings layer.

func (*SettingsManager) GetPromptTemplatePaths

func (sm *SettingsManager) GetPromptTemplatePaths() []string

GetPromptTemplatePaths returns the configured prompt template paths, or an empty list.

func (*SettingsManager) GetProviderRequestTimeoutMs

func (sm *SettingsManager) GetProviderRequestTimeoutMs() (int, error)

GetProviderRequestTimeoutMs returns the effective per-request stream/read timeout: retry.provider.timeoutMs when set, otherwise the httpIdleTimeoutMs. Mirrors upstream sdk.ts:311 (timeoutMs = providerRetrySettings.timeoutMs ?? effectiveTimeoutMs, where effectiveTimeoutMs is the httpIdleTimeoutMs). The sibling maxRetries/maxRetryDelayMs are consumed separately by the provider retry transport (ai.ConfigureProviderRetry).

func (*SettingsManager) GetProviderRetrySettings

func (sm *SettingsManager) GetProviderRetrySettings() ProviderRetryConfig

GetProviderRetrySettings returns provider retry settings with defaults applied. timeoutMs maps onto pig's net/http idle deadline (GetProviderRequestTimeoutMs); maxRetries/maxRetryDelayMs drive the provider retry transport (ai.ConfigureProviderRetry), mirroring the values upstream sdk.ts passes into retryProviderRequest.

func (*SettingsManager) GetQuietStartup

func (sm *SettingsManager) GetQuietStartup() QuietStartup

GetQuietStartup returns the quiet startup setting: true, "header" or false (settings-manager.ts:1089-1092).

func (*SettingsManager) GetRetryEnabled

func (sm *SettingsManager) GetRetryEnabled() bool

GetRetryEnabled returns whether automatic retries are enabled.

func (*SettingsManager) GetRetrySettings

func (sm *SettingsManager) GetRetrySettings() RetryConfig

GetRetrySettings returns retry settings with defaults applied. Mirrors upstream SettingsManager.getRetrySettings (settings-manager.ts:683-690).

func (*SettingsManager) GetSessionDir

func (sm *SettingsManager) GetSessionDir() (string, error)

GetSessionDir returns the configured session directory, expanding ~ forms and converting a file:// URL. An invalid file URL is an error, as upstream getSessionDir throws Node's fileURLToPath error.

func (*SettingsManager) GetSettings

func (sm *SettingsManager) GetSettings() Settings

GetSettings returns a copy of the effective settings: global and project settings merged, with overrides. Mirrors upstream getSettings (settings-manager.ts:564-566).

func (*SettingsManager) GetShellCommandPrefix

func (sm *SettingsManager) GetShellCommandPrefix() string

GetShellCommandPrefix returns the command prefix (e.g. "set -e; ").

func (*SettingsManager) GetShellPath

func (sm *SettingsManager) GetShellPath() (string, error)

GetShellPath returns the configured shell path (for bash tool). An invalid file URL is an error, as upstream getShellPath throws.

func (*SettingsManager) GetShowCacheMissNotices

func (sm *SettingsManager) GetShowCacheMissNotices() bool

GetShowCacheMissNotices returns whether transcript cache-miss notices are shown.

func (*SettingsManager) GetShowHardwareCursor

func (sm *SettingsManager) GetShowHardwareCursor() bool

GetShowHardwareCursor returns whether the hardware cursor is shown.

func (*SettingsManager) GetShowImages

func (sm *SettingsManager) GetShowImages() bool

GetShowImages returns whether inline images should be rendered.

func (*SettingsManager) GetShowTerminalProgress

func (sm *SettingsManager) GetShowTerminalProgress() bool

GetShowTerminalProgress returns whether OSC 9;4 terminal progress indicators are enabled.

func (*SettingsManager) GetSkillPaths

func (sm *SettingsManager) GetSkillPaths() []string

GetSkillPaths returns the configured skill paths, or an empty list.

func (*SettingsManager) GetSteeringMode

func (sm *SettingsManager) GetSteeringMode() string

GetSteeringMode returns the steering queue dispatch mode. Default: "one-at-a-time". Mirrors upstream getSteeringMode (settings-manager.ts:581).

func (*SettingsManager) GetTerminalCapabilityOverrides

func (sm *SettingsManager) GetTerminalCapabilityOverrides() tui.CapabilityOverrides

GetTerminalCapabilityOverrides mirrors upstream SettingsManager.getTerminalCapabilityOverrides over the merged settings.

func (*SettingsManager) GetTheme

func (sm *SettingsManager) GetTheme() string

GetTheme returns the configured fixed theme name, or "" for an automatic slash-separated theme setting.

func (*SettingsManager) GetThemePaths

func (sm *SettingsManager) GetThemePaths() []string

GetThemePaths returns the configured theme paths, or an empty list.

func (*SettingsManager) GetThemeSetting

func (sm *SettingsManager) GetThemeSetting() *string

GetThemeSetting returns the selected setting, preserving an omitted value separately from an explicitly empty name.

func (*SettingsManager) GetThinkingBudgets

func (sm *SettingsManager) GetThinkingBudgets() *ThinkingBudgetsSettings

GetThinkingBudgets returns custom thinking budgets, or nil.

func (*SettingsManager) GetTrackingID

func (sm *SettingsManager) GetTrackingID() string

GetTrackingID returns the analytics tracking identifier, or "". Mirrors upstream getTrackingId.

func (*SettingsManager) GetTransport

func (sm *SettingsManager) GetTransport() string

GetTransport returns the configured transport. Default: "auto".

func (*SettingsManager) GetTreeFilterMode

func (sm *SettingsManager) GetTreeFilterMode() string

GetTreeFilterMode returns the default /tree filter mode. Default: "default". Mirrors upstream SettingsManager.getTreeFilterMode (settings-manager.ts:954-955).

func (*SettingsManager) GetTuiMode

func (sm *SettingsManager) GetTuiMode() string

GetTuiMode returns the terminal UI mode: "regular" only when the setting says so, otherwise "fullscreen" (settings-manager.ts:1348-1350).

func (*SettingsManager) GetWarnings

func (sm *SettingsManager) GetWarnings() WarningSettings

GetWarnings returns warning settings.

func (*SettingsManager) GetWebSocketConnectTimeoutMs

func (sm *SettingsManager) GetWebSocketConnectTimeoutMs() (*int, error)

GetWebSocketConnectTimeoutMs returns the optional opening-handshake timeout; zero disables it.

func (*SettingsManager) GlobalPath

func (sm *SettingsManager) GlobalPath() string

GlobalPath returns the global settings file path, or empty for memory storage.

func (*SettingsManager) GlobalSettingsPath

func (sm *SettingsManager) GlobalSettingsPath() string

GlobalSettingsPath returns the global settings file path, or empty for memory storage.

func (*SettingsManager) IsInstallTelemetryEnabled

func (sm *SettingsManager) IsInstallTelemetryEnabled() bool

IsInstallTelemetryEnabled reports whether install/attribution telemetry is enabled, honoring the PI_TELEMETRY env override first and otherwise the enableInstallTelemetry setting (default true). Mirrors upstream isInstallTelemetryEnabled (telemetry.ts:8): when PI_TELEMETRY is set its truthiness wins; otherwise the setting decides. Gates provider attribution headers (provider-attribution.ts) in addition to package-install telemetry. pig divergence (D26): gates the OpenRouter/NVIDIA/Cloudflare attribution headers in coding/model.go.

func (*SettingsManager) IsProjectTrusted

func (sm *SettingsManager) IsProjectTrusted() bool

IsProjectTrusted reports whether project settings are readable and writable.

func (*SettingsManager) Load

func (sm *SettingsManager) Load()

Load reloads the backing settings layers and discards transient overrides. Previously recorded errors remain until DrainErrors.

func (*SettingsManager) Reload

func (sm *SettingsManager) Reload()

Reload refreshes the merged view from file or memory storage after earlier writes finish.

func (*SettingsManager) RemoveModelThinkingLevel

func (sm *SettingsManager) RemoveModelThinkingLevel(provider, modelID string) error

RemoveModelThinkingLevel clears a per-model default thinking level override. Mirrors upstream removeModelThinkingLevel.

func (*SettingsManager) ResolvedDefaultTools

func (sm *SettingsManager) ResolvedDefaultTools() []string

ResolvedDefaultTools returns the tools enabled at startup: the `defaultTools` setting, or the built-in defaults when no settings layer sets it. Mirrors upstream `getDefaultTools() ?? DEFAULT_TOOL_NAMES` (agent-session.ts:3593).

func (*SettingsManager) SetAutocompleteMaxVisible

func (sm *SettingsManager) SetAutocompleteMaxVisible(n int) error

SetAutocompleteMaxVisible sets max autocomplete items. Clamped to 3-20.

func (*SettingsManager) SetBlockImages

func (sm *SettingsManager) SetBlockImages(blocked bool) error

SetBlockImages sets whether image rendering is blocked.

func (*SettingsManager) SetCacheWarmingMode

func (sm *SettingsManager) SetCacheWarmingMode(mode CacheWarmingMode) error

SetCacheWarmingMode persists the cache-warming mode to global settings. Mirrors upstream setCacheWarmingMode.

func (*SettingsManager) SetClearOnShrink

func (sm *SettingsManager) SetClearOnShrink(enabled bool) error

SetClearOnShrink sets whether screen clears on terminal shrink.

func (*SettingsManager) SetCollapseChangelog

func (sm *SettingsManager) SetCollapseChangelog(collapse bool) error

SetCollapseChangelog sets whether changelog is collapsed.

func (*SettingsManager) SetCompactionEnabled

func (sm *SettingsManager) SetCompactionEnabled(enabled bool) error

SetCompactionEnabled enables or disables auto-compaction.

func (*SettingsManager) SetDefaultModel

func (sm *SettingsManager) SetDefaultModel(m string) error

SetDefaultModel sets the default model.

func (*SettingsManager) SetDefaultModelAndProvider

func (sm *SettingsManager) SetDefaultModelAndProvider(provider, model string) error

SetDefaultModelAndProvider sets both default model and provider atomically.

func (*SettingsManager) SetDefaultProvider

func (sm *SettingsManager) SetDefaultProvider(p string) error

SetDefaultProvider sets the default provider.

func (*SettingsManager) SetDefaultThinkingLevel

func (sm *SettingsManager) SetDefaultThinkingLevel(level string) error

SetDefaultThinkingLevel sets the default thinking level.

func (*SettingsManager) SetDoubleEscapeAction

func (sm *SettingsManager) SetDoubleEscapeAction(action string) error

SetDoubleEscapeAction sets the double-escape action.

func (*SettingsManager) SetEditorPaddingX

func (sm *SettingsManager) SetEditorPaddingX(padding int) error

SetEditorPaddingX sets horizontal editor padding. Clamped to 0-3.

func (*SettingsManager) SetEnableAnalytics

func (sm *SettingsManager) SetEnableAnalytics(enabled bool) error

SetEnableAnalytics saves the analytics opt-in. The first opt-in generates a random UUID tracking identifier, which later toggles keep. Mirrors upstream setEnableAnalytics.

func (*SettingsManager) SetEnableInstallTelemetry

func (sm *SettingsManager) SetEnableInstallTelemetry(enabled bool) error

SetEnableInstallTelemetry sets whether package-install telemetry is enabled. This toggles the gate only; delivery depends on the configured sender.

func (*SettingsManager) SetEnableSkillCommands

func (sm *SettingsManager) SetEnableSkillCommands(enabled bool) error

SetEnableSkillCommands sets whether skill commands are enabled.

func (*SettingsManager) SetEnabledModels

func (sm *SettingsManager) SetEnabledModels(patterns []string) error

SetEnabledModels sets the list of enabled models for Ctrl+P cycling.

func (*SettingsManager) SetExtensionPaths

func (sm *SettingsManager) SetExtensionPaths(paths []string) error

func (*SettingsManager) SetFollowUpMode

func (sm *SettingsManager) SetFollowUpMode(mode string) error

SetFollowUpMode sets the follow-up queue dispatch mode.

func (*SettingsManager) SetFullscreenCopyOnSelect

func (sm *SettingsManager) SetFullscreenCopyOnSelect(enabled bool) error

func (*SettingsManager) SetFullscreenExitOutput

func (sm *SettingsManager) SetFullscreenExitOutput(output string) error

func (*SettingsManager) SetFullscreenScrollbar

func (sm *SettingsManager) SetFullscreenScrollbar(mode string) error

func (*SettingsManager) SetFullscreenWheelScrollLines

func (sm *SettingsManager) SetFullscreenWheelScrollLines(lines WheelScrollLines) error

SetFullscreenWheelScrollLines saves the wheel line setting to global settings: auto, or a count floored and clamped to 1-100. Mirrors upstream setFullscreenWheelScrollLines (settings-manager.ts:1394-1399).

func (*SettingsManager) SetHideThinkingBlock

func (sm *SettingsManager) SetHideThinkingBlock(hide bool) error

SetHideThinkingBlock sets whether to hide thinking blocks.

func (*SettingsManager) SetHttpIdleTimeoutMs

func (sm *SettingsManager) SetHttpIdleTimeoutMs(timeoutMs float64) error

SetHttpIdleTimeoutMs sets the HTTP header/body idle timeout in milliseconds. Zero disables the timeout.

func (*SettingsManager) SetImageAutoResize

func (sm *SettingsManager) SetImageAutoResize(enabled bool) error

SetImageAutoResize sets whether images auto-resize.

func (*SettingsManager) SetImageWidthCells

func (sm *SettingsManager) SetImageWidthCells(width int) error

SetImageWidthCells sets the max image width in columns.

func (*SettingsManager) SetLastChangelogVersion

func (sm *SettingsManager) SetLastChangelogVersion(version string) error

SetLastChangelogVersion records that the user has seen changelog entries up to and including version. Persists to global settings. Mirrors upstream setLastChangelogVersion (settings-manager.ts:533-535).

func (*SettingsManager) SetMermaidRenderingMode

func (sm *SettingsManager) SetMermaidRenderingMode(mode string) error

func (*SettingsManager) SetModelThinkingLevel

func (sm *SettingsManager) SetModelThinkingLevel(provider, modelID, level string) error

SetModelThinkingLevel sets a per-model default thinking level override, keyed by "provider/modelID". Mirrors upstream setModelThinkingLevel.

func (*SettingsManager) SetNpmCommand

func (sm *SettingsManager) SetNpmCommand(cmd []string) error

SetNpmCommand sets the npm command override.

func (*SettingsManager) SetOutputPad

func (sm *SettingsManager) SetOutputPad(padding int) error

SetOutputPad sets horizontal chat output padding. Clamped to 0-1.

func (*SettingsManager) SetPackages

func (sm *SettingsManager) SetPackages(pkgs []PackageSource) error

SetPackages persists the global package source list, including an explicitly empty array.

func (*SettingsManager) SetProjectExtensionPaths

func (sm *SettingsManager) SetProjectExtensionPaths(paths []string) error

func (*SettingsManager) SetProjectPackages

func (sm *SettingsManager) SetProjectPackages(pkgs []PackageSource) error

SetProjectPackages persists the project package source list, including an explicitly empty array.

func (*SettingsManager) SetProjectPromptTemplatePaths

func (sm *SettingsManager) SetProjectPromptTemplatePaths(paths []string) error

func (*SettingsManager) SetProjectSkillPaths

func (sm *SettingsManager) SetProjectSkillPaths(paths []string) error

func (*SettingsManager) SetProjectThemePaths

func (sm *SettingsManager) SetProjectThemePaths(paths []string) error

func (*SettingsManager) SetProjectTrusted

func (sm *SettingsManager) SetProjectTrusted(trusted bool)

SetProjectTrusted changes project-settings access without reloading global settings. Unchanged trust preserves the current merged view. Ports packages/coding-agent/src/core/settings-manager.ts:515-537.

func (*SettingsManager) SetPromptTemplatePaths

func (sm *SettingsManager) SetPromptTemplatePaths(paths []string) error

func (*SettingsManager) SetQuietStartup

func (sm *SettingsManager) SetQuietStartup(quiet QuietStartup) error

SetQuietStartup sets the global quiet startup setting.

func (*SettingsManager) SetRetryEnabled

func (sm *SettingsManager) SetRetryEnabled(enabled bool) error

SetRetryEnabled enables or disables auto-retry.

func (*SettingsManager) SetShellCommandPrefix

func (sm *SettingsManager) SetShellCommandPrefix(prefix string) error

SetShellCommandPrefix sets the command prefix for bash commands.

func (*SettingsManager) SetShellPath

func (sm *SettingsManager) SetShellPath(path string) error

SetShellPath sets the shell path for the bash tool.

func (*SettingsManager) SetShowCacheMissNotices

func (sm *SettingsManager) SetShowCacheMissNotices(show bool) error

SetShowCacheMissNotices sets whether transcript cache-miss notices are shown.

func (*SettingsManager) SetShowHardwareCursor

func (sm *SettingsManager) SetShowHardwareCursor(enabled bool) error

SetShowHardwareCursor sets whether the hardware cursor is shown.

func (*SettingsManager) SetShowImages

func (sm *SettingsManager) SetShowImages(show bool) error

SetShowImages sets whether inline images are shown.

func (*SettingsManager) SetShowTerminalProgress

func (sm *SettingsManager) SetShowTerminalProgress(enabled bool) error

SetShowTerminalProgress sets whether OSC 9;4 terminal progress indicators are enabled.

func (*SettingsManager) SetSkillPaths

func (sm *SettingsManager) SetSkillPaths(paths []string) error

func (*SettingsManager) SetSteeringMode

func (sm *SettingsManager) SetSteeringMode(mode string) error

SetSteeringMode sets the steering queue dispatch mode.

func (*SettingsManager) SetTheme

func (sm *SettingsManager) SetTheme(theme string) error

SetTheme stores an explicit default theme; an empty name is not an omitted setting.

func (*SettingsManager) SetThemePaths

func (sm *SettingsManager) SetThemePaths(paths []string) error

func (*SettingsManager) SetTransport

func (sm *SettingsManager) SetTransport(transport string) error

SetTransport sets the HTTP transport mode.

func (*SettingsManager) SetTreeFilterMode

func (sm *SettingsManager) SetTreeFilterMode(mode string) error

SetTreeFilterMode sets the tree filter mode.

func (*SettingsManager) SetTuiMode

func (sm *SettingsManager) SetTuiMode(mode string) error

SetTuiMode sets the terminal UI mode.

func (*SettingsManager) SetWarnings

func (sm *SettingsManager) SetWarnings(warnings WarningSettings) error

SetWarnings sets warning settings.

func (*SettingsManager) UpdateGlobal

func (sm *SettingsManager) UpdateGlobal(fn func(*Settings)) error

UpdateGlobal applies fn and refreshes the merged view, then saves to the selected backing storage. Like Pi's setters (settings-manager.ts:668-682), the change stays in effect in memory when the global file had parse errors, which skips the save, or when the save fails.

func (*SettingsManager) UpdateProject

func (sm *SettingsManager) UpdateProject(fn func(*Settings)) error

UpdateProject applies fn to trusted project settings and refreshes the merged view, then saves to the selected storage. Like Pi's saveProjectSettings (settings-manager.ts:684-698), an untrusted project refuses the change, and otherwise the change stays in effect in memory when the project file had parse errors, which skips the save, or when the save fails.

type ShareState

type ShareState struct {
	SystemPrompt string
	Tools        []ShareTool
}

ShareState is the agent state the pi.share entry records: upstream session.state.systemPrompt and session.state.tools.

func NewShareState

func NewShareState(systemPrompt string, tools []agent.AgentTool) ShareState

NewShareState captures the system prompt and the active agent tools.

type ShareTool

type ShareTool struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Parameters  any    `json:"parameters,omitempty"`
}

ShareTool is one tool schema recorded in the pi.share entry.

type SkillDef

type SkillDef struct {
	SourceInfo             PiSourceInfo
	Name                   string
	Description            string
	DisableModelInvocation bool
	// Body is the markdown content (stripped of frontmatter).
	Body string
	// Path is the source Markdown file.
	Path string
	// Dir is the skill's containing directory: used so callers can
	// resolve referenced sibling files.
	Dir string
}

SkillDef is a parsed Markdown skill with frontmatter and body.

Pig loads these on `--skill <name>` and appends the body to the system prompt under a `## Skills` heading.

func DeduplicateSkills

func DeduplicateSkills(defs []*SkillDef) []*SkillDef

DeduplicateSkills keeps the first definition for each public name, matching Pi's collision behavior after Resource paths are ordered by precedence.

func DeduplicateSkillsWithDiagnostics

func DeduplicateSkillsWithDiagnostics(defs []*SkillDef) ([]*SkillDef, []extension.ResourceDiagnostic)

DeduplicateSkillsWithDiagnostics keeps the first name, silently ignores repeated real paths, and reports later same-name definitions in input order. Ports packages/coding-agent/src/core/skills.ts

func LoadSkill

func LoadSkill(skillsDir, name string) (*SkillDef, error)

LoadSkill loads a skill by name from `<skillsDir>/<name>/SKILL.md`.

Lookup order (mirrors upstream resource-loader's user-vs-project precedence):

  1. <pig-config>/skills/<name>/SKILL.md
  2. <skillsDir>/<name>/SKILL.md (caller-provided fallback root)

Most callers pass DefaultAgentDir()/skills as skillsDir so the Pig agent tree is searched first; we keep the parameter so SDK consumers can point at a vendored skills tree without env juggling.

func LoadSkillPath

func LoadSkillPath(path string) (*SkillDef, error)

LoadSkillPath loads a skill from a SKILL.md file path or a skill directory.

func LoadSkillsFromPath

func LoadSkillsFromPath(path string) ([]*SkillDef, error)

LoadSkillsFromPath loads one or more skills from a path in discovery order, without sorting by frontmatter name. Supported forms:

  • /path/to/skill/SKILL.md
  • /path/to/skill-dir/ (contains SKILL.md)
  • /path/to/skills-root/ (contains child dirs with SKILL.md)

type SlashCommand

type SlashCommand struct {
	Name        string
	Description string
	Handler     func(ctx *ExtensionContext, args string) error
}

SlashCommand is a command registered via /name.

type SlashCommandCatalog

type SlashCommandCatalog struct {
	Runner          ExtensionCommandLister
	PromptTemplates []PromptTemplate
	Skills          []*SkillDef
	CWD             string
	AgentDir        string
	SourceInfo      map[string]ResourceSourceInfo
}

SlashCommandCatalog lists the commands upstream AgentSession's getCommands (agent-session.ts _bindExtensionCore) and RPC get_commands report: extension commands, then prompt templates, then skills.

func (SlashCommandCatalog) Commands

func (c SlashCommandCatalog) Commands() []PiSlashCommand

Commands returns the catalog in upstream order.

func (SlashCommandCatalog) SourceInfoForPath

func (c SlashCommandCatalog) SourceInfoForPath(path, kind string) PiSourceInfo

SourceInfoForPath returns the SourceInfo of a resource of kind ("extensions", "prompts" or "skills") loaded from path.

func (SlashCommandCatalog) SubprocessCommands

func (c SlashCommandCatalog) SubprocessCommands() []subprocess.CommandInfo

SubprocessCommands returns SlashCommandCatalog.Commands in the subprocess wire shape.

func (SlashCommandCatalog) WithSkillSources

func (c SlashCommandCatalog) WithSkillSources(skills []*SkillDef) []*SkillDef

WithSkillSources projects loaded skills with the same resource provenance used by command discovery. Inline skills retain their authored metadata; file-backed skills use resolver and extension-discovery metadata. Ports packages/coding-agent/src/core/resource-loader.ts

type SlashCommandInfo

type SlashCommandInfo struct {
	Name        string
	Aliases     []string
	Description string
	Source      SlashCommandSource
}

SlashCommandInfo is the user-facing summary used by `/help`.

type SlashCommandSource

type SlashCommandSource string

SlashCommandSource mirrors upstream's `SlashCommandSource` discriminator.

const (
	SlashSourceBuiltin   SlashCommandSource = "builtin"
	SlashSourceExtension SlashCommandSource = "extension"
	SlashSourcePrompt    SlashCommandSource = "prompt" // <agentDir>/prompts/*.md
)

type SlashContext

type SlashContext struct {
	// Raw args after the command name (already trimmed). Empty if user
	// just typed `/foo` with no args.
	Args string

	// Output sinks: must be non-nil when Dispatch is called.
	Append     func(string) // append markdown to chat (Markdown component, 1px padding)
	AppendText func(string) // append plain ANSI text to chat (Text component, 1px padding)
	// AppendBlock appends Spacer(1) and Text(text, 1, 1), the confirmation
	// block upstream handlers such as handleDebugCommand add. The text is not
	// Markdown, so paths keep their backslashes.
	AppendBlock func(string)
	Clear       func() // clear the chat transcript
	Quit        func() // request session exit
	Reset       func() // /new: keep transcript visible but reset agent messages
	// NewSession creates a fresh session file and resets agent state.
	// Mirrors upstream runtimeHost.newSession(). May be nil in test contexts.
	NewSession func() error
	// FatalRuntimeError records an unrecoverable create/resume/import
	// replacement failure, then requests a status-1 exit after TUI teardown.
	FatalRuntimeError func(prefix string, err error) error

	// ShowStatus appends or updates the status line.
	ShowStatus  func(msg string)
	ShowWarning func(msg string)

	// Accessors. Any of these may be nil; handlers must guard. Keeps
	// the registry decoupled from the full InteractiveMode struct so
	// /help and friends are unit-testable in isolation.
	ModelName func() string
	// SelectedModelKey is `provider/id` of the session's selected model, the key of a single-model /session cost total.
	SelectedModelKey func() string
	ToolNames        func() []string
	// ToolRenderers returns how HTML exports draw tool calls; see [ExportToolRenderers].
	ToolRenderers func() func(name string) *extension.ToolRenderers
	// ShareState returns the system prompt and active tool schemas for the
	// pi.share entry attached to exported transcripts.
	ShareState func() ShareState
	// ShareSession uploads an explicitly requested share artifact. The host
	// captures the command context so cancellation reaches the HTTP request.
	ShareSession  func(session *Session, state ShareState, showStatus func(string)) (string, error)
	SkillNames    func() []string
	SessionInfo   func() (id, dir string, msgCount int)
	LastAssistant func() string
	CopyClipboard func(text string) error
	CostSummary   func() string
	ShowHotkeys   func()
	ShowChangelog func()

	// All registered commands: set by Dispatch before calling Handler
	// so /help can enumerate the live set.
	AllCommands []SlashCommandInfo

	// Session accessors. May be nil; handlers must guard.
	CurrentSession func() *Session
	// CacheWarmingStatus reports the Session's cache warmer, or nil when the
	// Session has none.
	CacheWarmingStatus func() *CacheWarmingStatus
	SetSessionName     func(name string) error
	GetSessionName     func() string
	// OnNameChange is called after a successful /name set so callers can
	// update the terminal title and status-line footer.
	OnNameChange func(name string)
	// ForkAtEntry moves the leaf to entryID IN THE SAME FILE (upstream
	// `session.branch`). Used by /tree navigation, not /fork.
	ForkAtEntry func(entryID string) error
	// FlushCompactionQueue delivers messages that were queued while a
	// compaction was running. Tree navigation calls it once the new leaf is in
	// place, mirroring upstream's flushCompactionQueue after "Navigated to
	// selected point" (interactive-mode.ts:1847, 5021), so a message typed
	// during compaction is not left queued by navigating away.
	FlushCompactionQueue func()
	// ForkToNewSession forks the selected user message into a NEW session
	// file (branch copied up to the message's parent), switches to it, and
	// prefills the editor with the message text. Mirrors upstream /fork
	// (agent-session-runtime.ts fork(), position "before").
	ForkToNewSession func(userMsgEntryID string) error
	// WriteDebugLog writes the current frame and message history to a debug
	// log file and returns its path. Backs /debug and the ctrl+shift+d hotkey.
	WriteDebugLog func() (path string, err error)
	CloneCurrent  func() (newPath string, err error)
	ListSessions  func() ([]SessionInfo, error)
	RenderTree    func() string

	// File-based prompt templates loaded from
	// <agentDir>/prompts and <cwd>/.pig/prompts. Read-only snapshot;
	// host populates this each Dispatch.
	PromptTemplates []PromptTemplate

	// Modal selector callbacks. Nil in headless or test
	// contexts; handlers must guard and fall back to text mode.
	PickSession     func() (path string, ok bool)
	PickUserMessage func() (entryID string, ok bool)
	PickTreeEntry   func(initialSelectedID string) (entryID string, ok bool)
	// AppendLabelChange writes a label entry for targetID.
	// label=="" clears any existing label (upstream: undefined→delete).
	AppendLabelChange func(targetID, label string) error
	LoadSessionPath   func(path string) error
	// ResumeStatus, when set, returns the status /resume shows after LoadSessionPath succeeds. The default is "Resumed session".
	ResumeStatus func() string
	// ImportSession imports a session JSONL file through the Session and
	// reports whether session_before_switch cancelled the switch. Mirrors
	// upstream runtimeHost.importFromJsonl.
	ImportSession func(inputPath, cwdOverride string) (cancelled bool, err error)

	// Manual context compaction.
	// CompactSession triggers a manual compact on the current session.
	// The closure captures the appropriate context internally.
	// nil in headless / test contexts unless explicitly wired.
	CompactSession func(customInstructions string) error

	// /tree summarize-branch flow.
	// ShowExtensionSelector presents a modal string picker with an optional
	// description under the title; returns the chosen option and true, or
	// ("", false) on cancel (Esc). Mirrors upstream showExtensionSelector()
	// and ExtensionSelectorOptions.description.
	ShowExtensionSelector func(title string, options []string, description string) (string, bool)
	// ShowTrustSelector invokes OnSelect before restoring the editor so persistence precedes closing the selector.
	ShowTrustSelector func(TrustSelectorOptions) (TrustSelection, bool)
	// ShowExtensionEditor presents a text prompt with an optional description
	// and prefill; returns the text and true, or ("", false) on cancel (Esc).
	// Mirrors upstream showExtensionEditor() and
	// ExtensionEditorOptions.description.
	ShowExtensionEditor func(title, description, prefill string) (string, bool)
	// BugReportInputs snapshots the process state /bug describes (model,
	// provider, thinking level, extensions, settings). Nil outside the
	// interactive UI.
	BugReportInputs func() (BugReportInputs, error)
	// BugReportProviderName names the current model's provider for the
	// summary consent text. May be nil.
	BugReportProviderName func() string
	// SummarizeForBugReport writes the /bug summary with the session model
	// behind a cancellable loader. aborted reports that the user cancelled.
	// May be nil.
	SummarizeForBugReport func(modelName, hint string) (summary string, aborted bool, err error)
	// UpstreamVersion returns the pinned Pi version. May be nil.
	UpstreamVersion func() string
	// CurrentTuiMode returns the running renderer's mode, independent of the saved default. Nil outside the interactive UI.
	CurrentTuiMode func() string
	// SwitchTuiMode switches the running renderer before the settings list saves a TUI mode, and returns false when the switch is refused. Nil outside the interactive UI.
	SwitchTuiMode func(mode string) bool
	// ShowSettingsList presents the dedicated two-column settings selector and
	// blocks until the user cancels. Each change calls onChange while the list
	// stays open with its selection and search, as upstream SettingsList's
	// onChange does; the row then shows the value onChange returns.
	ShowSettingsList func(items []tui.SettingItem, onChange func(id, value string) string)
	// ShowSettingsSubmenu is ShowSettingsList for a nested settings menu:
	// upstream builds those lists with Math.min(items.length, 10) rows and no
	// search.
	ShowSettingsSubmenu func(items []tui.SettingItem, onChange func(id, value string) string)
	// ShowSelectList presents a non-search submenu selector with optional
	// description column. Used by /settings for upstream-style submenus like
	// thinking level. Returns the chosen value or ("", false) on cancel.
	ShowSelectList func(title, description string, items []tui.SelectItem, currentValue string) (value string, ok bool)
	// ShowThemeSelector presents the theme submenu with live preview.
	// Used by /settings theme to mirror upstream theme preview semantics.
	ShowThemeSelector func(currentTheme string) (themeName string, ok bool)
	// AvailableThinkingLevels returns the currently supported levels for the
	// active model. Used by /settings to build the thinking submenu.
	AvailableThinkingLevels func() []string
	// CurrentThinkingLevel and SelectThinkingLevel back /thinking. May be nil.
	CurrentThinkingLevel func() string
	SelectThinkingLevel  func(level string)
	// ShowThinkingSelector opens the /thinking selector (upstream
	// showThinkingSelector). May be nil; /thinking then falls back to
	// ShowSelectList.
	ShowThinkingSelector func()
	// ModelThinkingSubmenu builds the per-model default override submenu.
	ModelThinkingSubmenu func(string, func(*string)) tui.Component
	// NavigateTreeFull forks to targetID and optionally generates a branch
	// summary. Mirrors upstream AgentSession.navigateTree() with summarize flag.
	NavigateTreeFull func(ctx context.Context, targetID string, summarize bool, customInstructions string) (NavigateTreeResult, error)
	// AbortBranchSummary cancels an in-progress branch summarization.
	AbortBranchSummary func()
	// SetEditorText sets the editor content (e.g. pre-filling user message
	// text when navigating to a user-message entry).
	SetEditorText func(text string)

	// Mid-session model switch.
	SwitchModel func(spec string) error

	PickModel    func(initialQuery string) (spec string, ok bool)
	ResolveModel func(input string) (spec string, ok bool)

	// /scoped-models selector.
	ShowScopedModels func() // opens editor-slot scoped-models list

	// Settings UI.
	// SettingsManager provides read/write access to global settings.
	SettingsManager *SettingsManager

	// Reload triggers a reload of settings and prompt templates.
	// Called by the /reload command. May be nil in headless contexts.
	Reload func() error

	// ReloadDiagnostics returns resource counts after a reload.
	// Mirrors upstream showLoadedResources with showDiagnosticsWhenQuiet.
	// May be nil; handler falls back to a static message.
	ReloadDiagnostics func() ReloadDiag

	// OnSettingApplied is called after /settings persists a change.
	// id is the setting identifier (e.g. "hide-thinking"), value is the new value.
	// Interactive mode uses this to apply live state changes (e.g. update
	// m.hideThinking without requiring a restart). May be nil.
	// Mirrors upstream settings-selector.ts callbacks (onHideThinkingChange etc.).
	OnSettingApplied func(id, value string)

	// AgentDir is the pig config dir (typically ~/.pig/agent).
	// Used by /login and /logout for auth.json access.
	AgentDir string

	// Parity harness hooks used only by env-gated test slash commands.
	ProbeClipboardRead     func() (string, error)
	ProbeImageFallback     func() (string, error)
	ProbeCancellableLoader func() (string, error)
	ProbeSelectList        func() (string, error)
	ProbeOAuthShared       func() (string, error)
	ProbeOAuthCallbackPage func() (string, error)
	ProbeCopilotHeaders    func() (string, error)
	ProbeOAuthCopilot      func() (string, error)
	ProbeOAuthCopilotEnv   func() (string, error)
	ProbeOAuthAnthropic    func() (string, error)
	ProbeOAuthCodex        func() (string, error)

	// Provider metadata and modal callbacks for /login and /logout.
	LoginProviders     func() []tui.OAuthProvider
	LogoutProviders    func() ([]tui.OAuthProvider, error)
	SelectAuthProvider func(mode string, providers []tui.OAuthProvider, initialSearch string) (tui.OAuthProvider, bool)
	// SelectAuthMethod returns "oauth" or "api_key", or the ID of a provider the top-level menu (nil providers) offers
	// directly, such as Radius.
	SelectAuthMethod func(providers []tui.OAuthProvider) (choice string, ok bool)
	// StartProviderLogin returns errLoginCancelled when the user cancels the login, which reopens the menu it was
	// started from.
	StartProviderLogin func(provider tui.OAuthProvider) error

	// Logout removes stored credentials for the given provider.
	// Mirrors upstream showOAuthSelector logout branch (interactive-mode.ts:4299).
	// May be nil in headless/test contexts; handlers must guard.
	Logout func(provider string) error

	// ExtRunner is the extension runner for emitting events from slash commands.
	// May be nil in headless/test contexts; handlers must guard.
	ExtRunner *inproc.Runner

	// Skills is the loaded set of skill definitions for /skill listing.
	Skills []*SkillDef
	// contains filtered or unexported fields
}

SlashContext is the per-dispatch context handed to a handler. Accessor fields are populated by the host (interactive mode); handlers read them and write user-visible output via the `Append` sink. `Quit` is the requested-exit signal: only `/exit` and `/quit` set it. `Clear` is requested by `/clear` and `/new`.

type SlashHandler

type SlashHandler func(sc *SlashContext) error

SlashHandler runs a builtin slash command. Handlers receive the SlashContext (which carries args + accessors + output sinks) and may return an error. A non-nil error causes the registry's Dispatch to surface "Error: <msg>" to the user.

type SlashRegistry

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

SlashRegistry holds builtins + extension-registered dynamic commands and resolves aliases. Concurrent-safe.

func NewSlashRegistry

func NewSlashRegistry() *SlashRegistry

NewSlashRegistry seeds a registry with the built-in commands.

func (*SlashRegistry) All

func (r *SlashRegistry) All() []SlashCommandInfo

All returns a sorted list of every command (builtin + extension) for /help rendering.

func (*SlashRegistry) Dispatch

func (r *SlashRegistry) Dispatch(sc *SlashContext, line string, extCtx *ExtensionContext) error

Dispatch parses a line like `/foo bar baz` and routes it. Returns ErrUnknownSlashCommand if the command is not registered (the caller should forward the text to the LLM). Returns other errors if the handler failed. The host is responsible for surfacing errors to the user: Dispatch itself does not call sc.Append for errors.

extCtx is the bridge to extension-registered commands (which take a different handler signature). May be nil if no extensions are loaded.

func (*SlashRegistry) IsBuiltin

func (r *SlashRegistry) IsBuiltin(name string) bool

IsBuiltin reports whether name (or an alias) is a built-in command, the commands upstream's onSubmit handles in its builtin chain.

func (*SlashRegistry) Register

func (r *SlashRegistry) Register(cmd BuiltinSlashCommand)

Register adds (or replaces) a builtin and its aliases. Used both internally for the seed list and externally if a host wants to inject extra builtins (tests do this).

func (*SlashRegistry) ReplaceDynamic

func (r *SlashRegistry) ReplaceDynamic(cmds []SlashCommand)

ReplaceDynamic replaces every extension-registered slash command with cmds, so a command whose extension is no longer loaded stops resolving.

func (*SlashRegistry) Resolve

func (r *SlashRegistry) Resolve(name string) (string, bool)

Resolve returns the canonical name for a typed-in command, walking aliases. Returns ("", false) if neither builtin nor extension command matches.

type StandaloneReceipt

type StandaloneReceipt struct {
	Kind              string
	ExecutablePath    string
	PigVersion        string
	SHA256            string
	UpdateSource      string
	UpdateTransportCA string
}

StandaloneReceipt binds a standalone install to the exact executable, release, update source, and installed bytes. The installer writes this owner-only receipt; Pig only validates it.

type StartupUIOptions

type StartupUIOptions struct {
	AgentDir   string
	Settings   Settings
	ThemePaths []string
}

type StatusLine

type StatusLine struct {
	tui.BaseComponent
	// contains filtered or unexported fields
}

StatusLine is the rich footer rendered at the bottom of the interactive viewport. Renders as two lines matching upstream pi's FooterComponent (footer.ts):

Line 1: ~/<pwd> (<branch>) • <session-name>
Line 2: ↑<in> ↓<out> $<cost> <context%>/<window> (auto)     <model> • <thinking>

Color coding on the context-% column (upstream thresholds):

<=70%  default (no color)
>70%   yellow (warning)
>90%   red (error)

All inputs are read on every Render() so the line reflects live state.

func NewStatusLine

func NewStatusLine(model *ai.Model, agentName string, timings *agent.Recorder) *StatusLine

NewStatusLine creates a StatusLine bound to the given model + agent. timings may be nil; cost/elapsed columns are then suppressed.

func (*StatusLine) Flash

func (s *StatusLine) Flash(msg string, ttl time.Duration)

Flash forwards status text to the interactive-mode chat status sink. The ttl argument is retained so existing callers do not need to change, but upstream-style status lines are not time-based footer overlays.

func (*StatusLine) GetExtensionStatuses

func (s *StatusLine) GetExtensionStatuses() map[string]string

GetExtensionStatuses returns a snapshot of all extension statuses. Used by diagnostics and the footer renderer.

func (*StatusLine) GetHiddenThinkingLabel

func (s *StatusLine) GetHiddenThinkingLabel() string

GetHiddenThinkingLabel returns the current hidden thinking label or "Thinking..." if not set.

func (*StatusLine) GetWorkingMessage

func (s *StatusLine) GetWorkingMessage() string

GetWorkingMessage returns the current custom working message or "".

func (*StatusLine) GitBranch

func (s *StatusLine) GitBranch() string

GitBranch returns the cached git branch, empty outside a repo.

func (*StatusLine) OnBranchChange

func (s *StatusLine) OnBranchChange(fn func()) func()

OnBranchChange subscribes to git-branch updates. Returns an unsubscribe.

func (*StatusLine) ProviderCount

func (s *StatusLine) ProviderCount() int

ProviderCount returns the number of authenticated, reachable providers.

func (*StatusLine) Render

func (s *StatusLine) Render(width int) []string

Render returns the footer lines (normally 2 plus keyed statuses).

func (*StatusLine) ResetContextUsage

func (s *StatusLine) ResetContextUsage()

ResetContextUsage clears the context-window column before a transcript rebuild re-reads it from the branch.

func (*StatusLine) SetAgentName

func (s *StatusLine) SetAgentName(name string)

SetAgentName updates the agent persona label.

func (*StatusLine) SetAutoCompactEnabled

func (s *StatusLine) SetAutoCompactEnabled(enabled bool)

SetAutoCompactEnabled updates the "(auto)" indicator.

func (*StatusLine) SetContextUsage

func (s *StatusLine) SetContextUsage(tokens *int, contextWindow int)

SetContextUsage stores the Session projection estimate outside the render path. Nil tokens indicate unknown usage after compaction until a valid response.

func (*StatusLine) SetCwd

func (s *StatusLine) SetCwd(cwd string)

SetCwd binds the footer and its branch watcher to the repository present at initialization.

func (*StatusLine) SetExtensionStatus

func (s *StatusLine) SetExtensionStatus(key, text string)

SetExtensionStatus sets (or clears) a keyed status entry in the footer's extension-status line. Mirrors upstream footer-data-provider.ts setStatus. Pass empty text to remove the key.

func (*StatusLine) SetHiddenThinkingLabel

func (s *StatusLine) SetHiddenThinkingLabel(label string)

SetHiddenThinkingLabel sets the label for hidden thinking blocks. Pass empty to restore the default "Thinking...". Mirrors upstream setHiddenThinkingLabel (interactive-mode.ts:1635-1649).

func (*StatusLine) SetModel

func (s *StatusLine) SetModel(m *ai.Model)

SetModel rebinds the model. Upstream footer.ts derives the subscription marker from the active model on every render, so a rebind re-evaluates it.

func (*StatusLine) SetName

func (s *StatusLine) SetName(name string)

SetName updates the session name shown in the footer.

func (*StatusLine) SetProviderCount

func (s *StatusLine) SetProviderCount(n int)

SetProviderCount updates the number of authenticated+reachable providers. When >1, the footer shows "(provider) model" instead of just "model". Mirrors upstream footer.ts:165-170.

func (*StatusLine) SetRoutedModelSource

func (s *StatusLine) SetRoutedModelSource(source func() *RoutedModelSelection)

SetRoutedModelSource installs the routed model read on each render.

func (*StatusLine) SetStatusHook

func (s *StatusLine) SetStatusHook(fn func(string))

func (*StatusLine) SetSubscriptionResolver

func (s *StatusLine) SetSubscriptionResolver(resolve func(*ai.Model) bool)

SetSubscriptionResolver installs the "(sub)" decision used by SetModel.

func (*StatusLine) SetSuppressedByExtFooter

func (s *StatusLine) SetSuppressedByExtFooter(v bool)

SetSuppressedByExtFooter controls whether an extension-owned footer replaces the complete standard footer, including the keyed status row. The custom footer receives those statuses through FooterData and owns their rendering.

func (*StatusLine) SetThinkingLevel

func (s *StatusLine) SetThinkingLevel(level string)

SetThinkingLevel updates the thinking level display.

func (*StatusLine) SetTurnContextUsage

func (s *StatusLine) SetTurnContextUsage(u *ai.Usage)

SetTurnContextUsage records the latest usage for the context-window column. Token and cost totals come from the usage totals source instead.

func (*StatusLine) SetUsageTotalsSource

func (s *StatusLine) SetUsageTotalsSource(source func() footerUsageTotals)

SetUsageTotalsSource installs the session usage totals read on each render.

func (*StatusLine) SetUsingSubscription

func (s *StatusLine) SetUsingSubscription(v bool)

SetUsingSubscription updates the OAuth subscription indicator. When true, cost display shows "(sub)". Mirrors upstream footer.ts:128.

func (*StatusLine) SetWorking

func (s *StatusLine) SetWorking(b bool)

SetWorking flips the spinner column on/off.

func (*StatusLine) SetWorkingMessage

func (s *StatusLine) SetWorkingMessage(message string)

SetWorkingMessage sets a custom message shown during streaming. Pass empty to restore the default spinner. Mirrors upstream loadingAnimation.setMessage (interactive-mode.ts:1877-1885).

type StdinBuffer

type StdinBuffer = tui.StdinBuffer

StdinBuffer is the shared UTF-16 framing state used by terminal owners.

func NewStdinBuffer

func NewStdinBuffer(options StdinBufferOptions) *StdinBuffer

type StdinBufferOptions

type StdinBufferOptions = tui.StdinBufferOptions

type SteppedSubmenu

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

SteppedSubmenu selects dependent values, goes back one step on Escape, and optionally loops after completion.

func NewSteppedSubmenu

func NewSteppedSubmenu(steps []SteppedSubmenuStep, onComplete func(map[string]string), onCancel func(), opts SteppedSubmenuOptions) *SteppedSubmenu

func (*SteppedSubmenu) HandleInput

func (s *SteppedSubmenu) HandleInput(data string)

func (*SteppedSubmenu) Invalidate

func (s *SteppedSubmenu) Invalidate()

func (*SteppedSubmenu) Render

func (s *SteppedSubmenu) Render(width int) []string

type SteppedSubmenuOptions

type SteppedSubmenuOptions struct {
	StartAtStep    int
	InitialContext map[string]string
	Loop           bool
}

SteppedSubmenuOptions controls the initial step and completion behavior.

type SteppedSubmenuStep

type SteppedSubmenuStep struct {
	Key         string
	Title       func(map[string]string) string
	Description func(map[string]string) string
	Options     func(map[string]string) []tui.SelectItem
	Preselect   func(map[string]string) string
	Layout      tui.SelectSubmenuOptions
}

SteppedSubmenuStep resolves its title, description, and options from earlier selections. Functions represent both constant and context-dependent upstream strings.

type SubprocessHost

type SubprocessHost interface {
	Reload(ctx context.Context) ([]extension.Extension, error)
	ExtensionCount() int
	LastReloadReport() *subprocess.ReloadReport
	LoadErrors() []string
	SetWidthFunc(fn func() int)
	SetHeightFunc(fn func() int)
	NotifyWidth(width int)
	NotifyHeight(height int)
	SetCrashHandler(fn func(name string, delay time.Duration, disabled bool, reason string))
	IsShuttingDown() bool
}

SubprocessHost is the interface for managing subprocess extension lifecycle during reload. Satisfied by *subprocess.Host.

pig-specific: no upstream equivalent.

type SubprocessUIBridge

type SubprocessUIBridge interface {
	SetInvalidate(fn func())
	SetNotifyFunc(fn func(message, level string))
	SetUIContext(ctx extension.UIContext)
	// SetUIPromptScope binds the runner that reports subprocess ui_prompt_start
	// and ui_prompt_end events.
	SetUIPromptScope(scope subprocess.UIPromptScope)
	// SetHostAction sets a named host callback. Known keys:
	// "getFlag", "getActiveTools", "getAllTools", "getCommands", "getThinkingLevel",
	// "setThinkingLevel", "getContextUsage", "getSystemPrompt", "isIdle",
	// "abort", "hasPendingMessages", "shutdown", "waitForIdle", "reload",
	// "sendUserMessage", "getSessionName", "setSessionName", "setLabel".
	SetHostAction(key string, fn any)
	PublishModelCatalog()
	// SetWidgetSyncFunc sets a callback invoked whenever an extension sets
	// or clears a widget. The callback receives all current widget proxies
	// as *subprocess.PushProxy values (keyed by "extName:widgetKey").
	SetWidgetSyncFunc(fn func(widgets map[string]*subprocess.PushProxy))
}

SubprocessUIBridge is the interface satisfied by *subprocess.UIBridge for wiring subprocess extension UI after TUI creation.

pig-specific: no upstream equivalent.

type TUIUIContext

type TUIUIContext struct {

	// NotifyFunc receives styled notification text when no interactive mode is attached.
	NotifyFunc func(message string)
	// contains filtered or unexported fields
}

TUIUIContext implements ExtensionUIContext for interactive mode.

func NewTUIUIContext

func NewTUIUIContext(t tui.Renderer) *TUIUIContext

NewTUIUIContext creates a TUI-backed ExtensionUIContext.

func (*TUIUIContext) Confirm

func (u *TUIUIContext) Confirm(title, message string) bool

func (*TUIUIContext) Input

func (u *TUIUIContext) Input(title, placeholder string) (string, bool)

func (*TUIUIContext) Notify

func (u *TUIUIContext) Notify(message, level string)

func (*TUIUIContext) Select

func (u *TUIUIContext) Select(title string, options []string) (string, bool)

func (*TUIUIContext) SetStatus

func (u *TUIUIContext) SetStatus(key, text string)

func (*TUIUIContext) SetWidget

func (u *TUIUIContext) SetWidget(key string, lines []string)

type ThinkingBudgetsSettings

type ThinkingBudgetsSettings struct {
	Minimal *int `json:"minimal,omitempty"`
	Low     *int `json:"low,omitempty"`
	Medium  *int `json:"medium,omitempty"`
	High    *int `json:"high,omitempty"`
}

ThinkingBudgetsSettings mirrors upstream ThinkingBudgetsSettings. Custom token budgets for each thinking level. Mirrors upstream settings-manager.ts ThinkingBudgetsSettings.

type ThinkingLevelEntry

type ThinkingLevelEntry struct {
	SessionEntryBase
	ThinkingLevel string `json:"thinkingLevel"`
}

ThinkingLevelEntry records a user-initiated thinking level change (Shift+Tab). Mirrors upstream appendThinkingLevelChange in agent-session.ts. Persisted as type="thinking_level_change" so the session tree can display [thinking: level].

type ThinkingSelectorComponent

type ThinkingSelectorComponent struct {
	*tui.Container
	// contains filtered or unexported fields
}

ThinkingSelectorComponent renders the /thinking selector: a search input over the available levels, the current level marked with a check, the saved default annotated, and app.thinking.save to save the highlighted level as the default. Ports upstream components/thinking-selector.ts.

func NewThinkingSelectorComponent

func NewThinkingSelectorComponent(
	currentLevel string,
	availableLevels []string,
	onSelect func(level string),
	onCancel func(),
	onSelectAsDefault func(level string),
	defaultThinkingLevel string,
) *ThinkingSelectorComponent

NewThinkingSelectorComponent builds the selector. onSelectAsDefault may be nil, which disables the save binding; defaultThinkingLevel annotates that level's description.

func (*ThinkingSelectorComponent) GetSelectList

func (s *ThinkingSelectorComponent) GetSelectList() *tui.FilterableList

GetSelectList returns the level list, as upstream getSelectList.

func (*ThinkingSelectorComponent) HandleInput

func (s *ThinkingSelectorComponent) HandleInput(data string)

HandleInput routes a key: the save binding saves the highlighted level as the default, navigation keys drive the list, and everything else edits the search query.

type TierError

type TierError struct {
	Tier        SelfUpdateTier
	ExePath     string
	Remediation string
	Cause       error
}

TierError reports that tier resolution could not select exactly one owner, or that the selected tier refused mutation. It carries the executable path and a concrete, non-looping remediation so the caller surfaces it verbatim.

func (*TierError) Error

func (e *TierError) Error() string

func (*TierError) Unwrap

func (e *TierError) Unwrap() error

type ToolCallEventResult

type ToolCallEventResult struct {
	Block  bool   `json:"block"`
	Reason string `json:"reason,omitempty"`
}

ToolCallEventResult controls whether an extension allows a tool call.

type ToolRendererCard

type ToolRendererCard struct {
	Component *tui.ToolExecutionComponent
	// contains filtered or unexported fields
}

ToolRendererCard owns one built-in card and its asynchronous invalidations. Its Component is mutated and rendered on the presentation owner loop; Dispose runs off-loop, cancels invalidations and joins all ticker/preview work. An already running filesystem preview finishes before Dispose returns.

func NewToolRendererCard

func NewToolRendererCard(ctx context.Context, name, toolCallId, cwd string, args json.RawMessage, renderers ToolRenderers, requestRender func()) *ToolRendererCard

NewToolRendererCard binds shared renderers to an independent card. An empty pair retains the native card's unregistered-tool path. RequestRender must be safe from a background invalidation.

func (*ToolRendererCard) Dispose

func (card *ToolRendererCard) Dispose()

Dispose cancels the card and joins its existing work. Repeated callers wait for the same disposal. State is fenced before waiting, so rendering cannot start another background task after disposal begins.

type ToolRenderers

type ToolRenderers struct {
	RenderCall   extension.ToolRenderCallFunc
	RenderResult extension.ToolRenderResultFunc
}

ToolRenderers is the built-in presentation pair, without a tool implementation or parameter schema.

type TrailingEntries

type TrailingEntries func(parentID *string, timestamp string) []any

TrailingEntries builds export-only entries appended after the branch. It receives the last branch entry ID (nil for an empty branch) and the export timestamp. Mirrors upstream TrailingEntries.

type TrustSelection

type TrustSelection struct {
	Trusted bool
	Updates []ProjectTrustUpdate
}

type TrustSelectorComponent

type TrustSelectorComponent struct {
	*tui.Container
	// contains filtered or unexported fields
}

func NewTrustSelectorComponent

func NewTrustSelectorComponent(options TrustSelectorOptions) *TrustSelectorComponent

func (*TrustSelectorComponent) HandleInput

func (s *TrustSelectorComponent) HandleInput(data string)

type TrustSelectorOptions

type TrustSelectorOptions struct {
	Cwd            string
	SavedDecision  *ProjectTrustStoreEntry
	ProjectTrusted bool
	OnSelect       func(TrustSelection)
	OnCancel       func()
}

type UpdateBinary

type UpdateBinary struct {
	URL    string `json:"url"`
	SHA256 string `json:"sha256"`
}

UpdateBinary is one platform's download URL and expected SHA256 (hex).

type UpdateManifest

type UpdateManifest struct {
	Version     string                  `json:"version"`
	PackageName string                  `json:"packageName"`
	Notes       string                  `json:"notes,omitempty"`
	Binaries    map[string]UpdateBinary `json:"binaries"`
}

UpdateManifest is the document an update source returns: the latest version plus a per-platform binary URL and checksum. Host-agnostic so any static host or marketplace can serve it. Binaries is keyed by "<goos>/<goarch>".

func FetchUpdateManifest

func FetchUpdateManifest(ctx context.Context, client *http.Client, rawURL string, options ...FetchUpdateManifestOptions) (*UpdateManifest, error)

FetchUpdateManifest reads, authenticates, and parses the exact update manifest at rawURL. Explicit updates retry transport failures and transient HTTP statuses twice within one version-check budget; authentication and parsing failures are terminal.

func (*UpdateManifest) PlatformBinary

func (m *UpdateManifest) PlatformBinary() (UpdateBinary, bool)

PlatformBinary returns the manifest's binary for the current platform.

type UsageEntry

type UsageEntry struct {
	SessionEntryBase
	// Kind is an arbitrary usage category, such as "cache_warm".
	Kind     string   `json:"kind"`
	Provider string   `json:"provider"`
	Model    string   `json:"model"`
	Usage    ai.Usage `json:"usage"`
	// Note is an optional human-readable qualifier for usage notices.
	Note string `json:"note,omitempty"`
}

UsageEntry is model-attributed usage that does not enter LLM context, such as a cache-warming refresh. Mirrors upstream session-manager.ts UsageEntry.

type WarningSettings

type WarningSettings struct {
	AnthropicExtraUsage bool `json:"anthropicExtraUsage,omitempty"`
	// contains filtered or unexported fields
}

WarningSettings mirrors upstream warning settings.

func (WarningSettings) MarshalJSON

func (w WarningSettings) MarshalJSON() ([]byte, error)

func (*WarningSettings) UnmarshalJSON

func (w *WarningSettings) UnmarshalJSON(data []byte) error

type WheelScrollLines

type WheelScrollLines struct {
	Auto  bool
	Lines float64
}

WheelScrollLines is the number of lines a wheel event scrolls, or Auto for velocity-based acceleration (upstream `WheelScrollLines = number | "auto"`). Lines is 1 to 100 when read from settings.

Source Files

Directories

Path Synopsis
Ports packages/coding-agent/src/core/compaction/branch-summarization.ts Branch summarization for tree navigation.
Ports packages/coding-agent/src/core/compaction/branch-summarization.ts Branch summarization for tree navigation.
Ports packages/coding-agent/src/core/export-html/ansi-to-html.ts
Ports packages/coding-agent/src/core/export-html/ansi-to-html.ts
Ports packages/coding-agent/src/utils/frontmatter.ts.
Ports packages/coding-agent/src/utils/frontmatter.ts.
Package llama ports Pi's built-in llama.cpp extension (packages/coding-agent/src/extensions/llama/): the router HTTP/SSE client, Hugging Face search and download, the dynamic provider, the manager UI, and the /llama command.
Package llama ports Pi's built-in llama.cpp extension (packages/coding-agent/src/extensions/llama/): the router HTTP/SSE client, Hugging Face search and download, the dynamic provider, the manager UI, and the /llama command.
Package prompts builds the default coding-agent system prompt.
Package prompts builds the default coding-agent system prompt.
tools/bash_executor.go: user bash execution (!cmd, RPC bash, SDK ExecuteBash).
tools/bash_executor.go: user bash execution (!cmd, RPC bash, SDK ExecuteBash).

Jump to

Keyboard shortcuts

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