filesystem

package module
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package filesystem provides reusable filesystem tool implementations for the ore tool extension.

It exports pre-built ReadFile, WriteFile, EditFile, ListDirectory and SearchFiles tool functions together with their tool.Tool JSON-schema descriptors, so applications can register them in a tool.Registry without defining the logic inline.

Usage:

registry := tool.NewRegistry()
if err := registry.Register(ReadFileTool.Name, ReadFileTool.Description, ReadFileTool.Schema, ReadFile); err != nil {
    ...
}
if err := registry.Register(WriteFileTool.Name, WriteFileTool.Description, WriteFileTool.Schema, WriteFile); err != nil {
    ...
}
if err := registry.Register(EditFileTool.Name, EditFileTool.Description, EditFileTool.Schema, EditFile); err != nil {
    ...
}
if err := registry.Register(ListDirectoryTool.Name, ListDirectoryTool.Description, ListDirectoryTool.Schema, ListDirectory); err != nil {
    ...
}
if err := registry.Register(SearchFilesTool.Name, SearchFilesTool.Description, SearchFilesTool.Schema, SearchFiles); err != nil {
    ...
}

// Registry.Tools() is the single source of truth for the provider.
tools := registry.Tools()

See also: x/tool/filesystem/filesystem.go for the tool implementations.

Index

Constants

This section is empty.

Variables

View Source
var EditFileTool = tool.Tool{
	Name:        "edit_file",
	Description: "Edit an existing file by replacing the first exact occurrence of old_string with new_string. Fails if old_string is empty or not found. Returns a short acknowledgement.",
	Schema: map[string]any{
		"type": "object",
		"properties": map[string]any{
			"path": map[string]any{
				"type":        "string",
				"description": "The relative or absolute path to the file to edit.",
			},
			"old_string": map[string]any{
				"type":        "string",
				"description": "The exact text to search for in the file. Must match literally (case-sensitive).",
			},
			"new_string": map[string]any{
				"type":        "string",
				"description": "The replacement text to insert in place of old_string.",
			},
		},
		"required": []string{"path", "old_string", "new_string"},
	},
	DisplayHint: func(args map[string]any) any {
		return &editDisplay{
			Old: toString(args["old_string"]),
			New: toString(args["new_string"]),
		}
	},
}

EditFileTool is the tool.Tool descriptor for EditFile.

View Source
var ListDirectoryTool = tool.Tool{
	Name: "list_directory",
	Description: "List the immediate non-hidden entries in a directory. Returns entry names. " +
		"Hidden entries (names starting with '.') are excluded.\n\n" +
		"Output limits: capped at 500 entries by default. Use the limit " +
		"parameter to control the cap. When truncated, the result includes a " +
		"hint to use a higher limit to see more.",
	Schema: map[string]any{
		"type": "object",
		"properties": map[string]any{
			"path": map[string]any{
				"type":        "string",
				"description": "The relative or absolute path to the directory to list.",
			},
			"limit": map[string]any{
				"type":        "integer",
				"description": "Maximum number of entries to return. Defaults to 500.",
				"default":     frameworkDefaultListRows,
			},
		},
		"required": []string{"path"},
	},
	DisplayHint: func(args map[string]any) any {
		return fmt.Sprintf("📁 list_directory(%s)", toString(args["path"]))
	},
	Format: tool.Format{
		Truncate: tool.TruncateConfig{
			MaxLines: frameworkDefaultListRows,
		},
		Style:        tool.StyleHead,
		RecoveryHint: "Output truncated. Use limit=2N to see more entries, or limit=N to reduce.",
	},
}

ListDirectoryTool is the tool.Tool descriptor for ListDirectory.

View Source
var ReadFileTool = tool.Tool{
	Name: "read_file",
	Description: "Read the contents of a file. Returns line-number-prefixed content.\n\n" +
		"Output limits: when the line-numbered output exceeds 50 KB / 2000 " +
		"lines, the full file is written to a temp file and only the head " +
		"of the line-numbered content is returned.\n\n" +
		"Recovery: when truncation occurs, the result includes the temp file " +
		"path. Read the temp file with read_file to access the full content, " +
		"or use a more specific offset/limit.",
	Schema: map[string]any{
		"type": "object",
		"properties": map[string]any{
			"path": map[string]any{
				"type":        "string",
				"description": "The relative or absolute path to the file to read.",
			},
			"offset": map[string]any{
				"type":        "integer",
				"description": "The 1-based line number to start reading from. Defaults to 1.",
				"default":     1,
			},
			"limit": map[string]any{
				"type":        "integer",
				"description": "The maximum number of lines to return. 0 means no limit.",
				"default":     0,
			},
		},
		"required": []string{"path"},
	},
	DisplayHint: func(args map[string]any) any {
		return fmt.Sprintf("📄 read_file(%s)", toString(args["path"]))
	},
	Format: tool.Format{
		Truncate: tool.TruncateConfig{
			MaxBytes: frameworkDefaultByteCap,
			MaxLines: 2000,
		},
		Style:        tool.StyleHead,
		RecoveryHint: "Output truncated. Use offset={next_offset} to continue, or read the full file at {path}.",
	},
}

ReadFileTool is the tool.Tool descriptor for ReadFile.

View Source
var SearchFilesTool = tool.Tool{
	Name: "search_files",
	Description: "Search files for lines matching a regex query. Returns matches with file path, line number, and matching line content. If the path is a directory, searches recursively. Hidden files and directories are skipped.\n\n" +
		"Output limits: capped at 1000 matches by default. Use the limit " +
		"parameter to control the cap. When truncated, the result includes a " +
		"hint to use a higher limit or a more specific regex.",
	Schema: map[string]any{
		"type": "object",
		"properties": map[string]any{
			"path": map[string]any{
				"type":        "string",
				"description": "The relative or absolute file or directory path to search.",
			},
			"query": map[string]any{
				"type":        "string",
				"description": "The regex pattern to search for.",
			},
			"limit": map[string]any{
				"type":        "integer",
				"description": "Maximum number of matches to return. Defaults to 1000.",
				"default":     frameworkDefaultSearchRows,
			},
		},
		"required": []string{"path", "query"},
	},
	DisplayHint: func(args map[string]any) any {
		return fmt.Sprintf("🔍 search_files(%s, %s)", toString(args["path"]), toString(args["query"]))
	},
	Format: tool.Format{
		Truncate: tool.TruncateConfig{
			MaxLines: frameworkDefaultSearchRows,
		},
		Style:        tool.StyleHead,
		RecoveryHint: "Output truncated. Use limit=2N to see more matches, or refine the regex.",
	},
}

SearchFilesTool is the tool.Tool descriptor for SearchFiles.

View Source
var WriteFileTool = tool.Tool{
	Name:        "write_file",
	Description: "Create or overwrite a file with the specified content. Returns a short acknowledgement.",
	Schema: map[string]any{
		"type": "object",
		"properties": map[string]any{
			"path": map[string]any{
				"type":        "string",
				"description": "The relative or absolute path to the file to create.",
			},
			"content": map[string]any{
				"type":        "string",
				"description": "The content to write into the file.",
			},
		},
		"required": []string{"path", "content"},
	},
	DisplayHint: func(args map[string]any) any {
		return &writeDisplay{
			Path:    toString(args["path"]),
			Content: toString(args["content"]),
		}
	},
}

WriteFileTool is the tool.Tool descriptor for WriteFile.

Functions

func EditFile

func EditFile(ctx context.Context, sb tool.Sandbox, args map[string]any) (any, error)

EditFile performs an exact-match search-and-replace on an existing file. It replaces the first occurrence of old_string with new_string. Parameters:

  • path (string, required): relative or absolute file path.
  • old_string (string, required): exact text to search for.
  • new_string (string, required): replacement text.

func ListDirectory

func ListDirectory(ctx context.Context, sb tool.Sandbox, args map[string]any) (any, error)

ListDirectory returns a shallow listing of non-hidden entries in a directory. Parameters:

  • path (string, required): relative or absolute directory path.
  • limit (number, optional, default 500): maximum entries to return.

func ReadFile

func ReadFile(ctx context.Context, sb tool.Sandbox, args map[string]any) (any, error)

ReadFile reads a file and returns its line-numbered content with byte-cap truncation and temp-file fallback. When the line-numbered output exceeds the cap, the full file is written to a temp file and the result's TempFilePath points to it; the LLM can read the temp file to retrieve the rest.

Parameters:

  • path (string, required): relative or absolute file path.
  • offset (number, optional, default 1): 1-based starting line.
  • limit (number, optional, default 0): maximum lines to return (0 = no limit).

func SearchFiles

func SearchFiles(ctx context.Context, sb tool.Sandbox, args map[string]any) (any, error)

SearchFiles searches files for lines matching a regex query. Parameters:

  • path (string, required): file or directory path to search.
  • query (string, required): regex pattern to match.
  • limit (number, optional, default 1000): maximum matches to return.

func WriteFile

func WriteFile(ctx context.Context, sb tool.Sandbox, args map[string]any) (any, error)

WriteFile creates a new file with the given content, overwriting if it exists. Parameters:

  • path (string, required): relative or absolute file path.
  • content (string, required): file contents to write.

Types

type EditFileResult added in v0.5.1

type EditFileResult struct {
	Path    string
	Message string
}

EditFileResult carries the acknowledgement returned by EditFile. Like WriteFileResult, the type implements both LLMRenderer and MarkdownRenderer so the TUI renders the ack as a clean fenced code block rather than JSON-quoted noise.

func (*EditFileResult) MarshalLLM added in v0.5.1

func (r *EditFileResult) MarshalLLM() string

MarshalLLM returns the LLM-facing acknowledgement.

func (*EditFileResult) MarshalMarkdown added in v0.5.1

func (r *EditFileResult) MarshalMarkdown() string

MarshalMarkdown returns the Markdown representation of the acknowledgement for human display. See WriteFileResult for the rationale behind wrapping the message in a code fence.

type ListDirectoryResult added in v0.5.0

type ListDirectoryResult struct {
	Entries    []string
	Truncation *artifact.Truncation
}

ListDirectoryResult carries the bounded entry list from a list_directory call, plus optional truncation metadata.

func (*ListDirectoryResult) MarshalLLM added in v0.5.0

func (r *ListDirectoryResult) MarshalLLM() string

MarshalLLM returns the LLM-facing string representation. The base content is a newline-separated list of entries. When truncation occurred, a recovery hint is appended that recommends a higher limit.

func (*ListDirectoryResult) MarshalMarkdown added in v0.5.1

func (r *ListDirectoryResult) MarshalMarkdown() string

MarshalMarkdown returns the Markdown representation of the result for human display. The entry list is wrapped in a fenced code block so glamour preserves the newlines between names. When truncation occurred, a short recovery hint follows the code block.

type ReadFileResult added in v0.5.0

type ReadFileResult struct {
	// Content is the line-numbered, possibly-truncated file
	// content. Always present; empty if the file is empty or
	// the offset is past EOF.
	Content string

	// TempFilePath is the path to a temp file holding the full
	// file content, set when truncation occurred. Empty when
	// no truncation occurred.
	TempFilePath string

	// Truncation is non-nil when the LLM-facing content was
	// truncated. The Truncation.OriginalBytes reflects the
	// byte length of the line-numbered output as produced by
	// the reader (i.e., the size of the bounded string the
	// user would have seen if no cap was in effect).
	Truncation *artifact.Truncation
}

ReadFileResult carries the bounded line-numbered content of a read_file call, plus optional truncation metadata and the path to a temp file that holds the full file content when the LLM-facing string was truncated.

func (*ReadFileResult) MarshalLLM added in v0.5.0

func (r *ReadFileResult) MarshalLLM() string

MarshalLLM returns the LLM-facing string representation. The base content is the bounded, line-numbered text. When truncation occurred, a recovery hint is appended that names the temp file and instructs the model to use offset={next_offset}.

func (*ReadFileResult) MarshalMarkdown added in v0.5.1

func (r *ReadFileResult) MarshalMarkdown() string

MarshalMarkdown returns the Markdown representation of the result for human display (e.g. the TUI). The line-numbered content is wrapped in a fenced code block so glamour preserves the line breaks and (when a language is recognised) syntax highlights the contents. When truncation occurred, a short recovery hint naming the temp file path is appended below the code block — a Markdown link keeps the path clickable in downstream Markdown renderers.

type SearchFilesResult added in v0.5.0

type SearchFilesResult struct {
	Results    []SearchResult
	Truncation *artifact.Truncation
}

SearchFilesResult carries the bounded match list from a search_files call, plus optional truncation metadata.

func (*SearchFilesResult) MarshalLLM added in v0.5.0

func (r *SearchFilesResult) MarshalLLM() string

MarshalLLM returns the LLM-facing string representation. The base content is one line per match ("path:line: content"). When truncation occurred, a recovery hint is appended recommending a higher limit or a more specific search.

func (*SearchFilesResult) MarshalMarkdown added in v0.5.1

func (r *SearchFilesResult) MarshalMarkdown() string

MarshalMarkdown returns the Markdown representation of the result for human display. Each match is wrapped in a fenced code block so the "path:line: content" framing is preserved verbatim (no soft-wrapping that would obscure the location). When truncation occurred, a short recovery hint follows.

type SearchResult

type SearchResult struct {
	Path       string `json:"path"`
	LineNumber int    `json:"line_number"`
	Content    string `json:"content"`
}

SearchResult represents a single regex match found by SearchFiles. It is serialized to JSON with fields:

  • path: the file path where the match was found,
  • line_number: the 1-based line index of the match,
  • content: the matching line text.

type WriteFileResult added in v0.5.1

type WriteFileResult struct {
	Path    string
	Bytes   int
	Message string
}

WriteFileResult carries the acknowledgement returned by WriteFile. The Message field holds the LLM-facing string (e.g. `wrote 42 bytes to "/foo"`). The type implements both artifact.LLMRenderer and artifact.MarkdownRenderer so the TUI can render the acknowledgement cleanly (as a fenced code block) instead of the JSON-shaped noise that json.Marshal(string) would produce.

func (*WriteFileResult) MarshalLLM added in v0.5.1

func (r *WriteFileResult) MarshalLLM() string

MarshalLLM returns the LLM-facing acknowledgement.

func (*WriteFileResult) MarshalMarkdown added in v0.5.1

func (r *WriteFileResult) MarshalMarkdown() string

MarshalMarkdown returns the Markdown representation of the acknowledgement for human display. The ack is wrapped in a fenced code block so glamour preserves the formatting (otherwise a bare `wrote N bytes to "path"` string is JSON-marshaled by the framework's fallback path and rendered with literal quote characters and escape sequences).

Jump to

Keyboard shortcuts

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