Documentation
¶
Index ¶
- Constants
- Variables
- func AttemptPrettyPrint(w io.Writer, chatMessage pub_models.Message, username string, raw bool) error
- func ConfigDirPaths() []string
- func ConfigUpgradeMessage(configFileName string, added []string) string
- func CreateConfigDir(configPath string) error
- func CreateFile[T any](path string, toCreate *T) error
- func DeleteRange[T any](s []T, start, end int) ([]T, error)
- func EscapeEditorString(edited string) string
- func GetClaiCacheDir() (string, error)
- func GetClaiConfigDir() (string, error)
- func GetFirstTokens(prompt []string, n int) []string
- func IsTerminalWriter(w io.Writer) bool
- func LoadConfigFromFile[T any](configDirPath, configFileName string, migrationCb func(string) error, dflt *T) (T, error)
- func LoadConfigFromFileCollect[T any](configDirPath, configFileName string, migrationCb func(string) error, dflt *T) (T, []string, error)
- func LoadTheme(configDirPath string) error
- func NewMacroReader(inputs []string) io.Reader
- func NotificationBellEnabled() bool
- func PrepareDisplayMessage(msg pub_models.Message) pub_models.Message
- func PrintToolActivity(w io.Writer, call pub_models.Call, content string, termWidth, maxRows int) error
- func Prompt(stdinReplace string, args []string) (string, error)
- func RandomPrefix() string
- func ReadAndUnmarshal[T any](filePath string, config *T) error
- func ReplaceTildeWithHome(s string) (string, error)
- func ResolveConfigDirPath(configDir string, components []string) (string, error)
- func ReturnNonDefault[T comparable](a, b, defaultVal T) (T, error)
- func RoleColor(role string) string
- func RollingOutputEnabled() bool
- func RollingOutputWindowCellHeight() int
- func SaveBase64File(prefix, dir, b64JSON, extension string) (string, error)
- func SessionDimensions(w io.Writer) dimensions.Dimensions
- func ShortenedOutput(out string, maxShortenedNewlines int) string
- func SummarizeAsyncToolResult(name, content string) string
- func TableTheme() table.Theme
- func ThemeConfigPath(configDirPath string) string
- func ToolOutputRows() int
- func UnescapeEditorString(toEdit string) string
- func UpdateMessageTerminalMetadata(msg string, line *string, lineCount *int, termWidth int)
- func WriteFile[T any](path string, toWrite *T) error
- type ActivityViewport
- func (v *ActivityViewport) AppendReasoning(content string)
- func (v *ActivityViewport) AppendText(content string)
- func (v *ActivityViewport) AppendTool(call pub_models.Call, content string, maxRows int)
- func (v *ActivityViewport) Content() string
- func (v *ActivityViewport) DetachRenderedRegion() int
- func (v *ActivityViewport) FinishReasoning()
- func (v *ActivityViewport) FinishText()
- func (v *ActivityViewport) RemoveTextBlock() int
- func (v *ActivityViewport) Render(w io.Writer) error
- func (v *ActivityViewport) Resize(width, terminalHeight int)
- func (v *ActivityViewport) Rows() []string
- func (v *ActivityViewport) TextBlockActive() bool
- type ContextKey
- type RollingOutputConfig
- type Theme
Constants ¶
const MaxShortenedNewlines = 5
Variables ¶
var Live bool
Live controls whether macro mode switches to interactive stdin after consuming all macro inputs (true, default) or appends trailing "q\n" terminators for graceful auto-exit (false). Set by Setup() based on the --non-interactive flag.
var ReadonlyConfig bool
ReadonlyConfig makes config loads read-only: missing fields are filled in memory, but the file is never rewritten and no upgrade announcement is printed. Set for raw (machine-readable) runs so shell hooks and scripts never mutate the user's configs as a side effect (config migration design, Q5). This is what keeps a precmd hook running `clai -r chat dirv2` from silently migrating the configs before the user's own commands run.
Functions ¶
func AttemptPrettyPrint ¶
func AttemptPrettyPrint(w io.Writer, chatMessage pub_models.Message, username string, raw bool) error
AttemptPrettyPrint by first checking if the glow command is available, and if so, pretty print the chat message. If not found, simply print the message as is. If the message has ReasoningContent, it is rendered with reasoning color before the main content.
If w is nil, os.Stdout is used.
func ConfigDirPaths ¶
func ConfigDirPaths() []string
func ConfigUpgradeMessage ¶ added in v1.10.20
ConfigUpgradeMessage returns the announcement text for fields added to a config file, e.g. "added new field(s) to textConfig.json: stoploss".
func CreateConfigDir ¶
func CreateFile ¶
func DeleteRange ¶
DeleteRange removes elements in [start, end] (inclusive) from the slice and returns the new slice. Panics if indices are invalid. Works for any slice type (Go 1.18+).
func EscapeEditorString ¶ added in v1.10.11
func GetClaiCacheDir ¶
GetClaiCacheDir returns the path to the clai cache directory. The directory is located inside the user's cache directory as <UserCacheDir>/clai, unless overridden by CLAI_CACHE_DIR.
func GetClaiConfigDir ¶
GetClaiConfigDir returns the path to the clai configuration directory. The directory is located inside the user's configuration directory as <UserConfigDir>/.clai, unless overridden by CLAI_CONFIG_DIR.
func GetFirstTokens ¶
GetFirstTokens returns the first n tokens of the prompt, or the whole prompt if it has less than n tokens
func IsTerminalWriter ¶ added in v1.10.20
IsTerminalWriter reports whether w resolves to a terminal writer.
func LoadConfigFromFile ¶
func LoadConfigFromFileCollect ¶ added in v1.10.20
func LoadConfigFromFileCollect[T any]( configDirPath, configFileName string, migrationCb func(string) error, dflt *T, ) (T, []string, error)
LoadConfigFromFileCollect is LoadConfigFromFile without the stdout announcement. It returns the JSON paths of every field it added to a pre-existing file, e.g. "stoploss" or "stoploss.max-tokens-handover-instructions"; an empty list means the file needed no upgrade (or was freshly created). Callers whose own output would overwrite the announcement (e.g. the interactive setup wizard, whose TUI erases pre-wizard stdout) use this to announce after their output is done.
func LoadTheme ¶
LoadTheme loads (and possibly creates) the theme.json file within the config dir. It is safe to call multiple times. After loading, stores the theme for consumer access.
func NewMacroReader ¶ added in v1.10.17
NewMacroReader creates a reader that yields each input string as a line.
By default (Live=true), after all macro inputs are consumed the reader transparently switches to os.Stdin so the user continues interacting.
When Live is false (--non-interactive), 10 trailing "q\n" lines are appended for graceful termination through nested table loops.
Returns nil when inputs is empty or nil (caller should skip injection).
func NotificationBellEnabled ¶
func NotificationBellEnabled() bool
func PrepareDisplayMessage ¶ added in v1.10.10
func PrepareDisplayMessage(msg pub_models.Message) pub_models.Message
func PrintToolActivity ¶ added in v1.10.20
func PrintToolActivity(w io.Writer, call pub_models.Call, content string, termWidth, maxRows int) error
PrintToolActivity prints one non-raw tool execution as a header and its result. The model transcript remains independent from this display-only representation.
func Prompt ¶
Prompt returns the prompt by checking all the arguments and stdin. If there is no arguments, but data in stdin, stdin will become the prompt. If there are arguments and data in stdin, all stdinReplace tokens will be substituted with the data in stdin
func RandomPrefix ¶
func RandomPrefix() string
func ReadAndUnmarshal ¶
ReadAndUnmarshal by first finding the file, then attempting to read + unmarshal to T
func ReplaceTildeWithHome ¶
func ResolveConfigDirPath ¶
func ReturnNonDefault ¶
func ReturnNonDefault[T comparable](a, b, defaultVal T) (T, error)
func RollingOutputEnabled ¶ added in v1.10.20
func RollingOutputEnabled() bool
RollingOutputEnabled reports whether reasoning and tool activity share a rolling terminal viewport.
func RollingOutputWindowCellHeight ¶ added in v1.10.20
func RollingOutputWindowCellHeight() int
RollingOutputWindowCellHeight returns the maximum terminal cells (rows) for the shared rolling activity viewport.
func SaveBase64File ¶ added in v1.10.17
SaveBase64File decodes a base64 string and writes it to dir/prefix_random.extension. Falls back to /tmp on write failure.
func SessionDimensions ¶ added in v1.10.20
func SessionDimensions(w io.Writer) dimensions.Dimensions
SessionDimensions resolves the one terminal-size snapshot for w. The snapshot is bound to the writer's file descriptor, so the observed size matches the file the output is actually written to (R2-02): a terminal yields its live size, and a non-terminal writer, a failed read, or a reported zero size deterministically yields dimensions.Fallback (80x24). No error propagates, matching the legacy silent fallback. A nil writer resolves to os.Stdout.
This is the single width-discovery point of clai. Every width-aware render path either stores the result of this helper for its session (the querier's snapshot) or calls it once at the start of a standalone render operation.
func ShortenedOutput ¶
ShortenedOutput returns a shortened version of the output
func SummarizeAsyncToolResult ¶ added in v1.10.20
SummarizeAsyncToolResult returns the concise interactive representation of async tool output. Raw and redirected output bypass this helper.
func TableTheme ¶ added in v1.10.17
TableTheme returns the table.Theme derived from the current global theme.
func ThemeConfigPath ¶
ThemeConfigPath returns the fully qualified theme.json path.
func ToolOutputRows ¶ added in v1.10.20
func ToolOutputRows() int
ToolOutputRows returns the maximum terminal rows used for non-raw tool output.
func UnescapeEditorString ¶ added in v1.10.11
func UpdateMessageTerminalMetadata ¶
UpdateMessageTerminalMetadata updates the terminal metadata. Meaning the lineCount, to eventually clear the terminal
Types ¶
type ActivityViewport ¶ added in v1.10.20
type ActivityViewport struct {
// contains filtered or unexported fields
}
ActivityViewport keeps a bounded, display-only view of streamed reasoning, assistant prose, and tool activity. It never changes model or tool source data.
Storage is logical, not visual: each block keeps the full sanitized content (the source of truth) plus its display policy (kind, header and role colours, 2-space body indentation, and tool output-marker and ERROR: handling). Colours and indentation are re-derived at rewrap time, so a width change rewraps every retained block instead of reconstructing content from already wrapped rows. The active reasoning and text blocks coalesce streamed tokens into one open block; finished blocks keep their logical content until the retention policy evicts them (maxActivityBlocks blocks, each bounded by maxActivityBlockRunes). A terminal-height grow can therefore bring retained content back into view, bounded by retention, not by the last visible row count.
func NewActivityViewport ¶ added in v1.10.20
func NewActivityViewport(width, maxRows, terminalHeight int) *ActivityViewport
NewActivityViewport creates a viewport for all transient model activity. maxRows is the configured rolling-window cap; terminalHeight is the raw terminal height at creation. The effective height is min(maxRows, max(terminalHeight, 1)) from the start, so the viewport never renders taller than the terminal it writes to (R5-01). Resize takes raw terminal dimensions and keeps the same min(cap, terminal height) bound on later dimension changes.
func (*ActivityViewport) AppendReasoning ¶ added in v1.10.20
func (v *ActivityViewport) AppendReasoning(content string)
AppendReasoning adds a reasoning block. The warm colour applies only to its header; its indented body has the same neutral presentation as tool output. An open assistant-prose block is closed first so the reasoning starts a new block.
func (*ActivityViewport) AppendText ¶ added in v1.10.20
func (v *ActivityViewport) AppendText(content string)
AppendText adds an assistant-prose block to the same viewport. Streamed tokens coalesce into one block until FinishText or RemoveTextBlock closes it.
func (*ActivityViewport) AppendTool ¶ added in v1.10.20
func (v *ActivityViewport) AppendTool(call pub_models.Call, content string, maxRows int)
AppendTool adds a compacted tool block to the same viewport. An open assistant-prose or reasoning block is closed first so the tool starts a new block.
func (*ActivityViewport) Content ¶ added in v1.10.20
func (v *ActivityViewport) Content() string
Content returns the sanitized content of the open reasoning block, or "" when no reasoning block is open.
func (*ActivityViewport) DetachRenderedRegion ¶ added in v1.10.20
func (v *ActivityViewport) DetachRenderedRegion() int
DetachRenderedRegion transfers ownership of the rows already drawn to the caller. The retained activity history will render at the current cursor position on the next Render call.
func (*ActivityViewport) FinishReasoning ¶ added in v1.10.20
func (v *ActivityViewport) FinishReasoning()
FinishReasoning closes the current reasoning block. Its visible rows stay in the activity history, while the next reasoning event starts a new block.
func (*ActivityViewport) FinishText ¶ added in v1.10.20
func (v *ActivityViewport) FinishText()
FinishText closes the active assistant-prose block. Its visible rows stay in the activity history, while the next prose stream starts a new block.
func (*ActivityViewport) RemoveTextBlock ¶ added in v1.10.20
func (v *ActivityViewport) RemoveTextBlock() int
RemoveTextBlock removes the active assistant-prose block from the activity history and returns the number of rows removed. The final answer is removed this way so it prints below the window instead of remaining inside it. The active text block is the last retained block, so its rows are the cache tail.
func (*ActivityViewport) Render ¶ added in v1.10.20
func (v *ActivityViewport) Render(w io.Writer) error
Render redraws the viewport in its existing terminal region. A dirty viewport (after Resize or a partial write) emits one complete atomic frame: move up the previously drawn rows, clear down, and rewrite the full window. The diff path is used only for normal streaming appends: pure appends print below the previously drawn region without clearing, and a changed tail clears from the first changed row down. The whole update lands in one write, so the terminal never paints an intermediate blank frame. The cursor is left below the viewport so subsequent tool activity or answer text follows it. A partial or failed write leaves the viewport dirty; the next Render retries the full frame.
func (*ActivityViewport) Resize ¶ added in v1.10.20
func (v *ActivityViewport) Resize(width, terminalHeight int)
Resize applies new terminal dimensions to the viewport. It mutates state only: it stores the new width, computes the effective height as min(configured cap, terminal height), rewraps all retained blocks at the new width, invalidates the render bookkeeping, and marks the viewport dirty. It never writes to the writer and is a no-op when the supplied dimensions equal the current ones. Resize is invoked only from the serialized session loop, never from a signal callback; mutation and rendering stay on that loop, so no mutex is needed.
func (*ActivityViewport) Rows ¶ added in v1.10.20
func (v *ActivityViewport) Rows() []string
Rows returns the physical terminal rows currently visible in the viewport.
func (*ActivityViewport) TextBlockActive ¶ added in v1.10.20
func (v *ActivityViewport) TextBlockActive() bool
TextBlockActive reports whether an assistant-prose block is currently open.
type RollingOutputConfig ¶ added in v1.10.20
type RollingOutputConfig struct {
Enabled bool `json:"enabled"`
WindowCellHeight int `json:"windowCellHeight"`
}
RollingOutputConfig configures the shared rolling activity viewport that contains streamed reasoning and tool blocks.
type Theme ¶
type Theme struct {
Primary string `json:"primary"`
Secondary string `json:"secondary"`
Breadtext string `json:"breadtext"`
RoleSystem string `json:"roleSystem"`
RoleUser string `json:"roleUser"`
RoleTool string `json:"roleTool"`
RoleReasoning string `json:"roleReasoning"`
RoleOther string `json:"roleOther"`
NotificationBell bool `json:"notificationBell"`
TableItems int `json:"tableItems"`
ToolOutputRows int `json:"toolOutputRows"`
RollingOutput RollingOutputConfig `json:"rollingOutput"`
}
Theme holds ANSI color configuration for terminal output. Values are raw ANSI escape sequences (e.g. "\u001b[38;2;120;140;160m").
This file is loaded from <clai-config-dir>/theme.json on startup. If NO_COLOR is set truthy, all colorization should be disabled.
Keep this config stable; new fields should be appended with defaults. Users can customize their own theme.json.