util

package
v0.0.0-...-715532d Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2025 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Browser utilities for opening URLs in the default system browser across different platforms (Linux, macOS, Windows).

colors provides ANSI color constants and functions for terminal output moved from lib/colors.go to break import cycle with providers

execute.go handles execution of bash commands and file changes from Nina output

gitutil.go provides git repository utilities used across nina projects

recovery.go provides panic recovery and logging utilities used across nina projects

Package util provides utility functions for truncating output to token limits. This ensures NinaBash output doesn't exceed provider context windows.

Index

Constants

View Source
const (
	ColorRed     = "\033[31m"
	ColorGreen   = "\033[32m"
	ColorYellow  = "\033[33m"
	ColorBlue    = "\033[34m"
	ColorMagenta = "\033[35m"
	ColorCyan    = "\033[36m"
	ColorReset   = "\033[0m"
)

Variables

View Source
var (
	NinaOutputStart  = "<" + "NinaOutput" + ">"
	NinaOutputEnd    = "</" + "NinaOutput" + ">"
	NinaPathStart    = "<" + "NinaPath" + ">"
	NinaPathEnd      = "</" + "NinaPath" + ">"
	NinaContentStart = "<" + "NinaContent" + ">"
	NinaContentEnd   = "</" + "NinaContent" + ">"
	NinaStart        = "<" + "NinaChange" + ">"
	NinaEnd          = "</" + "NinaChange" + ">"
	NinaSearchStart  = "<" + "NinaSearch" + ">"
	NinaSearchEnd    = "</" + "NinaSearch" + ">"
	NinaReplaceStart = "<" + "NinaReplace" + ">"
	NinaReplaceEnd   = "</" + "NinaReplace" + ">"

	NinaChangeRangeStartStart = "<" + "NinaStart" + ">"
	NinaChangeRangeStartEnd   = "</" + "NinaStart" + ">"
	NinaChangeRangeEndStart   = "<" + "NinaEnd" + ">"
	NinaChangeRangeEndEnd     = "</" + "NinaEnd" + ">"

	NinaMessageStart = "<" + "NinaMessage" + ">"
	NinaMessageEnd   = "</" + "NinaMessage" + ">"
	NinaInputStart   = "<" + "NinaInput" + ">"
	NinaInputEnd     = "</" + "NinaInput" + ">"

	NinaPromptStart       = "<" + "NinaPrompt" + ">"
	NinaPromptEnd         = "</" + "NinaPrompt" + ">"
	NinaSystemPromptStart = "<" + "NinaSystemPrompt" + ">"
	NinaSystemPromptEnd   = "</" + "NinaSystemPrompt" + ">"
	NinaFileStart         = "<" + "NinaFile" + ">"
	NinaFileEnd           = "</" + "NinaFile" + ">"
	NinaPatchStart        = "<" + "NinaPatch" + ">"
	NinaPatchEnd          = "</" + "NinaPatch" + ">"

	NinaBashStart   = "<" + "NinaBash" + ">"
	NinaBashEnd     = "</" + "NinaBash" + ">"
	NinaStopStart   = "<" + "NinaStop" + ">"
	NinaStopEnd     = "</" + "NinaStop" + ">"
	NinaResultStart = "<" + "NinaResult" + ">"
	NinaResultEnd   = "</" + "NinaResult" + ">"

	NinaSuggestionStart = "<" + "NinaSuggestion" + ">"
	NinaSuggestionEnd   = "</" + "NinaSuggestion" + ">"
)

Functions

func AddLineNumbers

func AddLineNumbers(content string) string

addLineNumbers prefixes each line with a 1-based index for LLM context.

func ApplyFileUpdates

func ApplyFileUpdates(content string, updates []FileUpdate) (string, error)

ApplyFileUpdates applies a sorted list of updates to file content Updates should be pre-sorted by StartLine descending to avoid line number shifts

func ApplyRangeReplace

func ApplyRangeReplace(update FileUpdate, dryRun bool, sessionState *SessionState) (string, error)

ApplyRangeReplace applies a single FileUpdate (range or full rewrite) and returns the updated content.

Historical versions of the code (and the tests) expected the signature

func ApplyRangeReplace(update FileUpdate, dryRun bool, state *SessionState)

while the most recent refactor changed it to

func ApplyRangeReplace(content string, update FileUpdate)

which broke compilation of the test suite.

To restore compatibility we re-introduce the original three-parameter signature. When a SessionState is supplied we attempt to locate the original file content in the session so the helper can operate on the same data the AI saw. If the lookup fails, an empty string is used. The dryRun flag is accepted for API stability but currently has no behavioural effect.

func ApplyUpdatesWithSearch

func ApplyUpdatesWithSearch(originalContent, currentContent string, updates []FileUpdate) (string, []error)

ApplyUpdatesWithSearch applies updates to currentContent using exact text search/replace based on the original content. Returns the updated content and any errors.

func CalculateMessageTokens

func CalculateMessageTokens(role, content string) int

CalculateMessageTokens counts tokens for a message with role and content. Includes overhead for message structure in the API format.

func CalculateSystemPromptTokens

func CalculateSystemPromptTokens(systemPrompt string) int

CalculateSystemPromptTokens counts tokens for system prompts. System prompts may have additional formatting or wrapper overhead.

func CalculateTokens

func CalculateTokens(text string) int

CalculateTokens returns approximate token count using o200k tokenizer.

func CalculateToolDefinitionTokens

func CalculateToolDefinitionTokens(toolJSON string) int

CalculateToolDefinitionTokens counts tokens for tool definitions. Tools are sent as JSON structures with name, description, and parameters.

func CalculateTotalTokens

func CalculateTotalTokens(systemPrompt string, messages []map[string]string, toolDefs []string) int

CalculateTotalTokens counts all tokens for a complete API request. Includes system prompt, messages, and tool definitions.

func CleanThinkingOutput

func CleanThinkingOutput(text string) string

CleanThinkingOutput removes ANSI codes, emojis, and collapses multiple newlines

func ColoredStderr

func ColoredStderr(format string, args ...any)

TODO delete and inline this

func ExtractAll

func ExtractAll(src, start, stop string) ([]string, error)

collects all substrings between start and stop tags across src returns error on malformed tags, keeps order, no state utility for iterating tag-separated data in nina components

func ExtractNinaMessage

func ExtractNinaMessage(output string) (string, error)

func ExtractSingle

func ExtractSingle(src, start, stop string) (string, error)

substring between start and stop tags, returns empty if start missing errors when stop not found, no external state, safe helper generic tag parse shared by proxy and server code

func Format

func Format(v any) string

func FormatNinaResult

func FormatNinaResult(cmdResult *CommandResult, changeResult *ChangeResult) string

FormatNinaResult formats a command or change result as NinaResult XML

func GetAgentsDir

func GetAgentsDir() string

GetAgentsDir returns the appropriate agents directory path under ~/.agents/ with a subdirectory based on the sanitized current working directory

func GetAgentsSubdir

func GetAgentsSubdir(subdir string) string

GetAgentsSubdir returns a subdirectory path under the agents directory

func GetBoxBottom

func GetBoxBottom() string

GetBoxBottom returns a box bottom line like "+-------+".

func GetBoxLine

func GetBoxLine(text string) string

GetBoxLine returns a box line with centered text like "| TEST: name |".

func GetBoxTop

func GetBoxTop() string

GetBoxTop returns a box top line like "+-------+".

func GetClaudeVersion

func GetClaudeVersion() string

GetClaudeVersion returns the Claude CLI version, checking cache first

func GetGitRoot

func GetGitRoot() string

GetGitRoot returns the git repository root directory or empty string if not in a git repo

func GetSeparator

func GetSeparator() string

GetSeparator returns a string of dashes that is terminal width - 2.

func GetSeparatorWithText

func GetSeparatorWithText(text string) string

GetSeparatorWithText returns a separator with centered text like "-- text --".

func GetTerminalWidth

func GetTerminalWidth() int

GetTerminalWidth returns the current terminal width, defaulting to 80 if unable to determine.

func GroupUpdatesByFile

func GroupUpdatesByFile(updates []FileUpdate) map[string][]FileUpdate

GroupUpdatesByFile groups updates by filename while preserving order within each file

func HighlightNinaTags

func HighlightNinaTags(text string) string

HighlightNinaTags highlights all XML tags in green first, then Nina tags in blue

func IsNumeric

func IsNumeric(s string) bool

IsNumeric reports whether the string is entirely ASCII digits.

func Last

func Last[T any](xs []T) T

func LogRecover

func LogRecover()

LogRecover recovers from panic and logs the error with stack trace

func LogRecoverTo

func LogRecoverTo(logger *log.Logger)

LogRecoverTo recovers from panic and logs to the provided logger

func MapToStruct

func MapToStruct(m map[string]any, out any) error

func OpenBrowser

func OpenBrowser(url string) error

OpenBrowser opens the specified URL in the system's default web browser. Returns an error if the platform is unsupported or if the browser command fails to start.

func ParseNinaResult

func ParseNinaResult(input string) (*CommandResult, *ChangeResult, error)

ParseNinaResult extracts command/change results from input

func ParseNinaStop

func ParseNinaStop(output string) (string, error)

ParseNinaStop extracts stop reason from NinaOutput

func Pformat

func Pformat(v any) string

func Ptr

func Ptr[T any](val T) *T

func RecoverAndLog

func RecoverAndLog()

RecoverAndLog recovers from panic, logs it, and re-panics

func RecoverToError

func RecoverToError(err *error)

RecoverToError recovers from panic and returns it as an error

func RemoveFencedBlocks

func RemoveFencedBlocks(content string) string

removeFencedBlocks extracts code from markdown ``` fences discarding prose.

func Sha256Hex

func Sha256Hex(b []byte) string

func SharedParentDir

func SharedParentDir(pathMap map[string]string) string

SharedParentDir computes common parent directory across paths in pathMap.

func StripLineNumbers

func StripLineNumbers(content string) string

stripLineNumbers removes the "<num>: " prefix inserted by addLineNumbers.

func StructToMap

func StructToMap(v any) map[string]any

func TrimBlankLines

func TrimBlankLines(lines []string) []string

func TruncateBashOutput

func TruncateBashOutput(stdout, stderr string, maxTokens int) (string, string)

TruncateBashOutput truncates stdout and stderr for NinaBash results. Each field gets up to half the token budget, with unused tokens from one field available to the other. Priority is given to stdout.

func TruncateToTokenLimit

func TruncateToTokenLimit(text string, maxTokens int) string

TruncateToTokenLimit truncates a string to fit within the specified token limit. If truncation occurs, it appends "[truncated]" to the output. The function ensures the final output including the truncation marker doesn't exceed the token limit.

func ValidateFileUpdate

func ValidateFileUpdate(update FileUpdate, sessionState *SessionState) error

func ValidateRangeReplace

func ValidateRangeReplace(update FileUpdate, sessionState *SessionState) error

func ValueSlice

func ValueSlice[T any](val []*T) []T

Types

type BashCommand

type BashCommand struct {
	Command string
	Args    []string
}

BashCommand represents a bash command to execute

func ParseNinaBash

func ParseNinaBash(output string) ([]BashCommand, error)

ParseNinaBash extracts bash commands from NinaOutput

type ChangeResult

type ChangeResult struct {
	FilePath     string
	Args         []string
	Stdout       string
	Stderr       string
	Error        string
	LinesChanged int
}

ChangeResult represents the result of applying a file change

type CommandResult

type CommandResult struct {
	Command  string
	Cmd      string
	Cwd      string
	Args     []string
	ExitCode int
	Stdout   string
	Stderr   string
}

CommandResult represents the result of executing a command

func ExecuteBash

func ExecuteBash(cmd BashCommand, logNum int) CommandResult

ExecuteBash runs a bash command and returns the result

func ExecuteBashWithArgs

func ExecuteBashWithArgs(command string, args []string, logNum int) CommandResult

ExecuteBashWithArgs executes a bash command and returns the result

type FileUpdate

type FileUpdate struct {
	FileName     string
	SearchLines  []string
	ReplaceLines []string
	StartLine    int // 1-based inclusive start line for range updates
	EndLine      int // 1-based inclusive end line for range updates
}

func ParseFileUpdates

func ParseFileUpdates(output string) ([]FileUpdate, error)

func SortUpdatesForApplication

func SortUpdatesForApplication(updates []FileUpdate) []FileUpdate

SortUpdatesForApplication sorts updates within a file by StartLine descending This ensures that later edits don't affect earlier edit line numbers

type RangeResult

type RangeResult struct {
	Start int `json:"start"`
	End   int `json:"end"`
}

type SessionState

type SessionState struct {
	ID            string            `json:"id"`
	OrigFiles     map[string]string `json:"origFiles"`
	SelectedFiles map[string]string `json:"selectedFiles"`
	Updates       []FileUpdate      `json:"updates"`
	PathMap       map[string]string `json:"pathMap"`
	TempDir       string            `json:"tempDir"`
	Applied       bool              `json:"applied"`
}

type SessionUpdateData

type SessionUpdateData struct {
	Created       time.Time         `json:"created"`
	Type          string            `json:"type"`
	Updates       []FileUpdate      `json:"updates"`
	OrigFiles     map[string]string `json:"origFiles"`
	SelectedFiles map[string]string `json:"selectedFiles"`
	PathMap       map[string]string `json:"pathMap"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL