UNPKG

@earendil-works/pi-coding-agent

Version:

Coding agent CLI with read, bash, edit, write tools and session management

298 lines • 16.8 kB
import { Type } from "typebox"; import { ModelThinkingLevelSchema } from "./pi-ai-schemas.js"; import { SETTINGS_DEFAULTS } from "./settings-defaults.js"; function nonNegativeSafeInteger(options = {}) { return Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER, ...options }); } function timeoutSetting(options) { return Type.Union([Type.Number({ minimum: 0 }), Type.Literal("disabled")], options); } const CompactionModelOverrideSchema = Type.Object({ reserveTokens: Type.Optional(nonNegativeSafeInteger()), keepRecentTokens: Type.Optional(nonNegativeSafeInteger()), }); const CompactionSettingsSchema = Type.Object({ enabled: Type.Optional(Type.Boolean({ default: SETTINGS_DEFAULTS.compaction.enabled })), reserveTokens: Type.Optional(nonNegativeSafeInteger({ default: SETTINGS_DEFAULTS.compaction.reserveTokens })), keepRecentTokens: Type.Optional(nonNegativeSafeInteger({ default: SETTINGS_DEFAULTS.compaction.keepRecentTokens })), modelOverrides: Type.Optional(Type.Record(Type.String(), CompactionModelOverrideSchema, { description: 'Per-model overrides keyed by exact "provider/modelId" strings.', })), }); const BranchSummarySettingsSchema = Type.Object({ reserveTokens: Type.Optional(Type.Number({ description: "Tokens reserved for the prompt and LLM response.", default: SETTINGS_DEFAULTS.branchSummary.reserveTokens, })), skipPrompt: Type.Optional(Type.Boolean({ description: 'When true, skips the "Summarize branch?" prompt and defaults to no summary.', default: SETTINGS_DEFAULTS.branchSummary.skipPrompt, })), }); const ProviderRetrySettingsSchema = Type.Object({ timeoutMs: Type.Optional(Type.Number({ description: "SDK or provider request timeout in milliseconds." })), maxRetries: Type.Optional(Type.Number({ description: "SDK or provider retry attempts." })), maxRetryDelayMs: Type.Optional(Type.Number({ description: "Maximum server-requested delay before failing.", default: SETTINGS_DEFAULTS.retry.provider.maxRetryDelayMs, })), }); const RetrySettingsSchema = Type.Object({ enabled: Type.Optional(Type.Boolean({ default: SETTINGS_DEFAULTS.retry.enabled })), maxRetries: Type.Optional(Type.Number({ default: SETTINGS_DEFAULTS.retry.maxRetries })), baseDelayMs: Type.Optional(Type.Number({ description: "Exponential backoff base delay in milliseconds: 2s, 4s, 8s.", default: SETTINGS_DEFAULTS.retry.baseDelayMs, })), maxAgentDelayMs: Type.Optional(Type.Number({ default: SETTINGS_DEFAULTS.retry.maxAgentDelayMs })), provider: Type.Optional(ProviderRetrySettingsSchema), maxDelayMs: Type.Optional(Type.Number({ description: "Legacy retry delay setting. Use provider.maxRetryDelayMs instead.", deprecated: true, })), }); const TerminalSettingsSchema = Type.Object({ showImages: Type.Optional(Type.Boolean({ description: "Show images when the terminal supports them.", default: SETTINGS_DEFAULTS.terminal.showImages, })), imageWidthCells: Type.Optional(Type.Number({ description: "Preferred inline image width in terminal cells.", default: SETTINGS_DEFAULTS.terminal.imageWidthCells, })), clearOnShrink: Type.Optional(Type.Boolean({ description: "Clear empty rows when content shrinks.", default: SETTINGS_DEFAULTS.terminal.clearOnShrink, })), showTerminalProgress: Type.Optional(Type.Boolean({ description: "Show OSC 9;4 terminal progress indicators.", default: SETTINGS_DEFAULTS.terminal.showTerminalProgress, })), hyperlinks: Type.Optional(Type.Union([Type.Boolean(), Type.Literal("auto")])), images: Type.Optional(Type.Union([Type.Literal("kitty"), Type.Literal("iterm2"), Type.Literal("auto"), Type.Literal(false)])), trueColor: Type.Optional(Type.Union([Type.Boolean(), Type.Literal("auto")])), }); const ImageSettingsSchema = Type.Object({ autoResize: Type.Optional(Type.Boolean({ description: "Resize images to 2000x2000 maximum for better model compatibility.", default: SETTINGS_DEFAULTS.images.autoResize, })), blockImages: Type.Optional(Type.Boolean({ description: "When true, prevents all images from being sent to LLM providers.", default: SETTINGS_DEFAULTS.images.blockImages, })), }); function thinkingBudgetsSettings(options) { return Type.Object({ minimal: Type.Optional(Type.Number()), low: Type.Optional(Type.Number()), medium: Type.Optional(Type.Number()), high: Type.Optional(Type.Number()), }, options); } const ThinkingBudgetsSettingsSchema = thinkingBudgetsSettings(); const MarkdownSettingsSchema = Type.Object({ codeBlockIndent: Type.Optional(Type.String({ default: SETTINGS_DEFAULTS.markdown.codeBlockIndent })), mermaid: Type.Optional(Type.Union([Type.Literal("off"), Type.Literal("final"), Type.Literal("streaming")], { default: SETTINGS_DEFAULTS.markdown.mermaid, })), }); const WarningSettingsSchema = Type.Object({ anthropicExtraUsage: Type.Optional(Type.Boolean({ default: SETTINGS_DEFAULTS.warnings.anthropicExtraUsage })), }); function codemodeMode(options) { return Type.Union([Type.Literal("on"), Type.Literal("only")], options); } const CodemodeModeSchema = codemodeMode(); const CodemodeSettingsSchema = Type.Object({ mode: Type.Optional(codemodeMode({ description: 'How codemode presents tools. "on" keeps direct tools declared and annotates tools callable from scripts; codemode lists only tools without direct exposure. "only" lists every script-callable tool in codemode and does not declare active direct tools.', default: SETTINGS_DEFAULTS.codemode.mode, })), inlineBudget: Type.Optional(Type.Number({ minimum: 0, description: "Estimated tokens available for inline codemode tool declarations.", default: SETTINGS_DEFAULTS.codemode.inlineBudget, })), }); const PackageSourceSchema = Type.Union([ Type.String({ description: "Load all resources from the package." }), Type.Object({ source: Type.String(), autoload: Type.Optional(Type.Boolean({ description: "When false, start empty and only apply explicit resource patterns." })), extensions: Type.Optional(Type.Array(Type.String())), skills: Type.Optional(Type.Array(Type.String())), prompts: Type.Optional(Type.Array(Type.String())), themes: Type.Optional(Type.Array(Type.String())), }), ], { description: "Package source for npm or git packages. Use the string form to load all resources or the object form to filter resources.", }); const StringArraySchema = Type.Array(Type.String()); const SkillsInputSchema = Type.Union([ StringArraySchema, Type.Object({ enableSkillCommands: Type.Optional(Type.Boolean()), customDirectories: Type.Optional(StringArraySchema), }, { deprecated: true }), ], { description: "Local skill file paths or directories." }); export const SettingsSchema = Type.Object({ $schema: Type.Optional(Type.String({ description: "JSON Schema reference." })), lastChangelogVersion: Type.Optional(Type.String()), extensionChangelogVersions: Type.Optional(Type.Record(Type.String(), Type.String(), { description: "Last seen changelog version per extension package.", })), defaultProvider: Type.Optional(Type.String()), defaultModel: Type.Optional(Type.String()), defaultThinkingLevel: Type.Optional(ModelThinkingLevelSchema), modelThinkingLevels: Type.Optional(Type.Record(Type.String(), ModelThinkingLevelSchema, { description: 'Per-model default thinking level overrides keyed by "provider/modelId".', })), transport: Type.Optional(Type.Union([Type.Literal("auto"), Type.Literal("sse"), Type.Literal("websocket"), Type.Literal("websocket-cached")], { default: SETTINGS_DEFAULTS.transport })), sessionShareDestination: Type.Optional(Type.Union([Type.Literal("auto"), Type.Literal("gist"), Type.Literal("radius")], { description: 'Destination used by /share. "auto" uses Radius when authenticated and otherwise creates a GitHub gist.', default: SETTINGS_DEFAULTS.sessionShareDestination, })), steeringMode: Type.Optional(Type.Union([Type.Literal("all"), Type.Literal("one-at-a-time")], { default: SETTINGS_DEFAULTS.steeringMode, })), followUpMode: Type.Optional(Type.Union([Type.Literal("all"), Type.Literal("one-at-a-time")], { default: SETTINGS_DEFAULTS.followUpMode, })), theme: Type.Optional(Type.String()), compaction: Type.Optional(CompactionSettingsSchema), branchSummary: Type.Optional(BranchSummarySettingsSchema), retry: Type.Optional(RetrySettingsSchema), hideThinkingBlock: Type.Optional(Type.Boolean({ default: SETTINGS_DEFAULTS.hideThinkingBlock })), showCacheMissNotices: Type.Optional(Type.Boolean({ description: "Show cache cost and provider recovery notices.", default: SETTINGS_DEFAULTS.showCacheMissNotices, })), externalEditor: Type.Optional(Type.String({ description: "Command for Ctrl+G external editor; takes precedence over VISUAL and EDITOR." })), shellPath: Type.Optional(Type.String({ description: "Custom shell path, for example for Cygwin on Windows, with support for leading ~ expansion.", })), quietStartup: Type.Optional(Type.Union([Type.Boolean(), Type.Literal("header")], { description: 'When true, hide all startup output. When "header", keep only the startup header.', default: SETTINGS_DEFAULTS.quietStartup, })), defaultProjectTrust: Type.Optional(Type.Union([Type.Literal("ask"), Type.Literal("always"), Type.Literal("never")], { description: "Global setting only.", default: SETTINGS_DEFAULTS.defaultProjectTrust, })), shellCommandPrefix: Type.Optional(Type.String({ description: "Prefix prepended to every bash command, for example to enable shell aliases." })), npmCommand: Type.Optional(Type.Array(Type.String(), { description: 'Command used for npm package lookup and installation, in argv form such as ["mise", "exec", "node@20", "--", "npm"].', })), selfUpdateCommand: Type.Optional(Type.Array(Type.String(), { minItems: 1, description: 'Command `pi update` runs to update Pi itself, in argv form such as ["mise", "use", "-g", "npm:{packageName}@{version}"]. Placeholders: {packageName}, {version}, {installSpec}. PI_SELF_UPDATE_COMMAND takes precedence. Global setting only.', })), collapseChangelog: Type.Optional(Type.Boolean({ description: "Show the condensed changelog after update; use /changelog for the full changelog.", default: SETTINGS_DEFAULTS.collapseChangelog, })), enableInstallTelemetry: Type.Optional(Type.Boolean({ description: "Send an anonymous version and update ping after changelog-detected updates.", default: SETTINGS_DEFAULTS.enableInstallTelemetry, })), enableAnalytics: Type.Optional(Type.Boolean({ description: "Opt in to analytics data sharing.", default: SETTINGS_DEFAULTS.enableAnalytics, })), trackingId: Type.Optional(Type.String({ description: "Analytics tracking identifier, generated when analytics is enabled." })), packages: Type.Optional(Type.Array(PackageSourceSchema, { description: "npm or git package sources, as strings or objects with resource filtering.", })), extensions: Type.Optional(Type.Array(Type.String(), { description: "Local extension file paths or directories." })), deviceId: Type.Optional(Type.String({ description: "Stable installation UUID, generated when authentication first needs it. Global only.", })), skills: Type.Optional(SkillsInputSchema), prompts: Type.Optional(Type.Array(Type.String(), { description: "Local prompt template file paths or directories." })), themes: Type.Optional(Type.Array(Type.String(), { description: "Local theme file paths or directories." })), enableSkillCommands: Type.Optional(Type.Boolean({ description: "Register skills as /skill:name commands.", default: SETTINGS_DEFAULTS.enableSkillCommands, })), terminal: Type.Optional(TerminalSettingsSchema), images: Type.Optional(ImageSettingsSchema), enabledModels: Type.Optional(Type.Array(Type.String(), { description: "Model patterns for cycling, in the same format as the --models CLI flag.", })), defaultTools: Type.Optional(Type.Array(Type.String(), { description: "Initial tool selection. Plain names replace the inherited selection; +name and -name entries add or remove tools.", })), doubleEscapeAction: Type.Optional(Type.Union([Type.Literal("fork"), Type.Literal("tree"), Type.Literal("none")], { description: "Action for double-escape with an empty editor.", default: SETTINGS_DEFAULTS.doubleEscapeAction, })), treeFilterMode: Type.Optional(Type.Union([ Type.Literal("default"), Type.Literal("no-tools"), Type.Literal("user-only"), Type.Literal("labeled-only"), Type.Literal("all"), ], { description: "Default filter when opening /tree.", default: SETTINGS_DEFAULTS.treeFilterMode, })), thinkingBudgets: Type.Optional(thinkingBudgetsSettings({ description: "Custom token budgets for thinking levels.", })), editorPaddingX: Type.Optional(Type.Number({ description: "Horizontal padding for the input editor.", default: SETTINGS_DEFAULTS.editorPaddingX, })), outputPad: Type.Optional(Type.Union([Type.Literal(0), Type.Literal(1)], { description: "Horizontal padding for transcript content.", default: SETTINGS_DEFAULTS.outputPad, })), autocompleteMaxVisible: Type.Optional(Type.Number({ description: "Maximum visible items in the autocomplete dropdown.", default: SETTINGS_DEFAULTS.autocompleteMaxVisible, })), showHardwareCursor: Type.Optional(Type.Boolean({ description: "Show the terminal cursor while still positioning it for IME." })), markdown: Type.Optional(MarkdownSettingsSchema), warnings: Type.Optional(WarningSettingsSchema), codemode: Type.Optional(CodemodeSettingsSchema), sessionDir: Type.Optional(Type.String({ description: "Custom session storage directory, in the same format as the --session-dir CLI flag.", })), httpProxy: Type.Optional(Type.String({ description: "Proxy URL applied as HTTP_PROXY and HTTPS_PROXY for Pi-managed HTTP clients." })), httpIdleTimeoutMs: Type.Optional(timeoutSetting({ description: 'HTTP header or body idle timeout in milliseconds; 0 or "disabled" disables it.', })), cacheWarming: Type.Optional(Type.Union([Type.Literal("off"), Type.Literal("streaming"), Type.Literal("idle")], { description: 'Cache-warming profile. "idle" also warms between agent runs. Global only because each refresh costs money.', default: SETTINGS_DEFAULTS.cacheWarming, })), websocketConnectTimeoutMs: Type.Optional(timeoutSetting({ description: 'WebSocket connect or open handshake timeout in milliseconds; 0 or "disabled" disables it.', })), tuiMode: Type.Optional(Type.Union([Type.Literal("regular"), Type.Literal("fullscreen")], { default: SETTINGS_DEFAULTS.tuiMode, })), fullscreenExitOutput: Type.Optional(Type.Union([Type.Literal("transcript"), Type.Literal("resume-hint")], { description: "No effect in regular TUI mode.", default: SETTINGS_DEFAULTS.fullscreenExitOutput, })), fullscreenScrollbar: Type.Optional(Type.Union([Type.Literal("auto"), Type.Literal("always"), Type.Literal("hidden")], { description: "No effect in regular TUI mode.", default: SETTINGS_DEFAULTS.fullscreenScrollbar, })), fullscreenCopyOnSelect: Type.Optional(Type.Boolean({ description: "No effect in regular TUI mode.", default: SETTINGS_DEFAULTS.fullscreenCopyOnSelect, })), fullscreenWheelScrollLines: Type.Optional(Type.Union([Type.Number(), Type.Literal("auto")], { description: "Lines scrolled per wheel event in fullscreen mode; numeric values are clamped from 1 to 100.", default: SETTINGS_DEFAULTS.fullscreenWheelScrollLines, })), queueMode: Type.Optional(Type.Union([Type.Literal("all"), Type.Literal("one-at-a-time")], { description: "Legacy setting migrated to steeringMode.", deprecated: true, })), websockets: Type.Optional(Type.Boolean({ description: "Legacy setting migrated to transport.", deprecated: true })), }, { additionalProperties: true }); //# sourceMappingURL=settings-schema.js.map