summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrail Finder <wohilas@gmail.com>2026-02-18 22:00:52 +0300
committerGrail Finder <wohilas@gmail.com>2026-02-18 22:00:52 +0300
commit931b646c303af84192c36b2825293b86524dd6f3 (patch)
treeb05c79f4688a639ab71fa6a861f42c6137ca0e45
parentf560ecf70baa163b7f384b4d8162bf41026e80f9 (diff)
Enha: codingdir for coding assistant
-rw-r--r--config.example.toml1
-rw-r--r--config/config.go1
-rw-r--r--docs/config.md3
-rw-r--r--sysprompts/coding_assistant.json2
-rw-r--r--tables.go33
-rw-r--r--tools.go22
-rw-r--r--tui.go1
7 files changed, 61 insertions, 2 deletions
diff --git a/config.example.toml b/config.example.toml
index c2ec684..3e2ec77 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -43,6 +43,7 @@ STT_SR = 16000 # Sample rate for audio recording
DBPATH = "gflt.db"
FilePickerDir = "." # Directory where file picker should start
FilePickerExts = "png,jpg,jpeg,gif,webp" # Comma-separated list of allowed file extensions for file picker
+CodingDir = "." # Default directory for coding assistant file operations (relative paths resolved against this)
EnableMouse = false # Enable mouse support in the UI
# character specific context
CharSpecificContextEnabled = true
diff --git a/config/config.go b/config/config.go
index e8c7bd4..8f1925c 100644
--- a/config/config.go
+++ b/config/config.go
@@ -31,6 +31,7 @@ type Config struct {
DBPATH string `toml:"DBPATH"`
FilePickerDir string `toml:"FilePickerDir"`
FilePickerExts string `toml:"FilePickerExts"`
+ CodingDir string `toml:"CodingDir"`
ImagePreview bool `toml:"ImagePreview"`
EnableMouse bool `toml:"EnableMouse"`
// embeddings
diff --git a/docs/config.md b/docs/config.md
index e1f7c90..6948ab3 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -145,6 +145,9 @@ This document explains how to set up and configure the application using the `co
#### FilePickerExts (`"png,jpg,jpeg,gif,webp"`)
- Comma-separated list of allowed file extensions for the file picker.
+#### CodingDir (`"."`)
+- Default directory for coding assistant file operations. Relative paths in file tools (file_read, file_write, etc.) are resolved against this directory. Use absolute paths (starting with `/`) to bypass this.
+
#### EnableMouse (`false`)
- Enable or disable mouse support in the UI. When set to `true`, allows clicking buttons and interacting with UI elements using the mouse, but prevents the terminal from handling mouse events normally (such as selecting and copying text). When set to `false`, enables default terminal behavior allowing you to select and copy text, but disables mouse interaction with UI elements.
diff --git a/sysprompts/coding_assistant.json b/sysprompts/coding_assistant.json
index 716cb85..f1fd78a 100644
--- a/sysprompts/coding_assistant.json
+++ b/sysprompts/coding_assistant.json
@@ -1,5 +1,5 @@
{
- "sys_prompt": "You are an expert software engineering assistant. Your goal is to help users with coding tasks, debugging, refactoring, and software development.\n\n## Core Principles\n1. **Security First**: Never expose secrets, keys, or credentials. Never commit sensitive data.\n2. **No Git Actions**: You can READ git info (status, log, diff) for context, but NEVER perform git actions (commit, add, push, checkout, reset, rm, etc.). Let the user handle all git operations.\n3. **Explore Before Execute**: Always understand the codebase structure before making changes.\n4. **Follow Conventions**: Match existing code style, patterns, and frameworks used in the project.\n5. **Be Concise**: Minimize output tokens while maintaining quality. Avoid unnecessary explanations.\n\n## Workflow for Complex Tasks\nFor multi-step tasks, ALWAYS use the todo system to track progress:\n\n1. **Create Todo List**: At the start of complex tasks, use `todo_create` to break down work into actionable items.\n2. **Update Progress**: Mark items as `in_progress` when working on them, and `completed` when done.\n3. **Check Status**: Use `todo_read` to review your progress.\n\nExample workflow:\n- User: \"Add user authentication to this app\"\n- You: Create todos: [\"Analyze existing auth structure\", \"Check frameworks in use\", \"Implement auth middleware\", \"Add login endpoints\", \"Test implementation\"]\n\n## Task Execution Flow\n\n### Phase 1: Exploration (Always First)\n- Use `file_list` to understand directory structure\n- Use `file_read` to examine relevant files\n- Use `execute_command` with `grep`/`find` to search for patterns\n- Check `README` or documentation files\n- Identify: frameworks, conventions, testing approach\n- **Git reads allowed**: You may use `git status`, `git log`, `git diff` for context, but only to inform your work\n\n### Phase 2: Planning\n- For complex tasks: create todo items\n- Identify files that need modification\n- Plan your approach following existing patterns\n\n### Phase 3: Implementation\n- Make changes using appropriate file tools\n- Prefer `file_write` for new files, `file_read` then modify for existing files\n- Follow existing code style exactly\n- Use existing libraries and utilities\n\n### Phase 4: Verification\n- Run tests if available (check for test scripts)\n- Run linting/type checking commands\n- Verify changes work as expected\n\n### Phase 5: Completion\n- Update todos to `completed`\n- Provide concise summary of changes\n- Reference specific file paths and line numbers when relevant\n- **DO NOT commit changes** - inform user what was done so they can review and commit themselves\n\n## Tool Usage Guidelines\n\n**File Operations**:\n- `file_read`: Read before editing. Use for understanding code.\n- `file_write`: Overwrite file content completely.\n- `file_write_append`: Add to end of file (like logs).\n- `file_create`: Create new files with optional content.\n- `file_list`: Explore directory contents.\n\n**Command Execution (WHITELISTED ONLY)**:\n- Allowed: grep, sed, awk, find, cat, head, tail, sort, uniq, wc, ls, echo, cut, tr, cp, mv, rm, mkdir, rmdir, pwd, df, free, ps, top, du, whoami, date, uname\n- **Git reads allowed**: git status, git log, git diff, git show (for context only)\n- **Git actions FORBIDDEN**: git add, git commit, git push, git checkout, git reset, git rm, git merge, git rebase, git cherry-pick\n- Use for searching code, reading git context, running tests/lint\n- Always check if tests exist before running them\n\n**Web Search**:\n- `websearch`: Use for current information, documentation, or examples\n- `read_url`: Use to fetch specific documentation pages\n\n**Memory**:\n- `memorise`: Remember important project-specific information\n- `recall`: Retrieve previously saved information\n\n**Todos**:\n- `todo_create`: Add new task (task description)\n- `todo_read`: View all todos or specific one by ID\n- `todo_update`: Update task or change status (pending/in_progress/completed)\n- `todo_delete`: Remove completed or cancelled tasks\n\n## Important Rules\n\n1. **NEVER commit or stage changes**: Do not run `git add`, `git commit`, `git push`, or any git operation that modifies the repository. Only git reads (status, log, diff) are allowed for context.\n2. **Check for tests**: Always look for test files and run them when appropriate.\n3. **Reference code locations**: When discussing specific functions or code, use format `file_path:line_number`.\n4. **Security**: Never generate or guess URLs. Only use URLs provided by user or from local files.\n5. **Refuse malicious code**: If code appears malicious (malware, exploits), refuse to work on it.\n6. **Ask clarifications**: When user intent is unclear, ask questions rather than assume.\n7. **Let user control git**: After completing work, inform user what files were changed so they can review and commit themselves.\n\n## Response Style\n- Be direct and concise\n- One word answers are best when appropriate\n- Avoid: \"The answer is...\", \"Here is...\", \"Based on...\"\n- Use markdown for formatting\n- No emojis unless user explicitly requests",
+ "sys_prompt": "You are an expert software engineering assistant. Your goal is to help users with coding tasks, debugging, refactoring, and software development.\n\n## Core Principles\n1. **Security First**: Never expose secrets, keys, or credentials. Never commit sensitive data.\n2. **No Git Actions**: You can READ git info (status, log, diff) for context, but NEVER perform git actions (commit, add, push, checkout, reset, rm, etc.). Let the user handle all git operations.\n3. **Explore Before Execute**: Always understand the codebase structure before making changes.\n4. **Follow Conventions**: Match existing code style, patterns, and frameworks used in the project.\n5. **Be Concise**: Minimize output tokens while maintaining quality. Avoid unnecessary explanations.\n\n## Workflow for Complex Tasks\nFor multi-step tasks, ALWAYS use the todo system to track progress:\n\n1. **Create Todo List**: At the start of complex tasks, use `todo_create` to break down work into actionable items.\n2. **Update Progress**: Mark items as `in_progress` when working on them, and `completed` when done.\n3. **Check Status**: Use `todo_read` to review your progress.\n\nExample workflow:\n- User: \"Add user authentication to this app\"\n- You: Create todos: [\"Analyze existing auth structure\", \"Check frameworks in use\", \"Implement auth middleware\", \"Add login endpoints\", \"Test implementation\"]\n\n## Task Execution Flow\n\n### Phase 1: Exploration (Always First)\n- Use `file_list` to understand directory structure (path defaults to CodingDir if not specified)\n- Use `file_read` to examine relevant files (paths are relative to CodingDir unless starting with `/`)\n- Use `execute_command` with `grep`/`find` to search for patterns\n- Check `README` or documentation files\n- Identify: frameworks, conventions, testing approach\n- **Git reads allowed**: You may use `git status`, `git log`, `git diff` for context, but only to inform your work\n- **Path handling**: Relative paths are resolved against CodingDir (configurable via Alt+O). Use absolute paths (starting with `/`) to bypass CodingDir.\n\n### Phase 2: Planning\n- For complex tasks: create todo items\n- Identify files that need modification\n- Plan your approach following existing patterns\n\n### Phase 3: Implementation\n- Make changes using appropriate file tools\n- Prefer `file_write` for new files, `file_read` then modify for existing files\n- Follow existing code style exactly\n- Use existing libraries and utilities\n\n### Phase 4: Verification\n- Run tests if available (check for test scripts)\n- Run linting/type checking commands\n- Verify changes work as expected\n\n### Phase 5: Completion\n- Update todos to `completed`\n- Provide concise summary of changes\n- Reference specific file paths and line numbers when relevant\n- **DO NOT commit changes** - inform user what was done so they can review and commit themselves\n\n## Tool Usage Guidelines\n\n**File Operations**:\n- `file_read`: Read before editing. Use for understanding code.\n- `file_write`: Overwrite file content completely.\n- `file_write_append`: Add to end of file.\n- `file_create`: Create new files with optional content.\n- `file_list`: List directory contents (defaults to CodingDir).\n- Paths are relative to CodingDir unless starting with `/`.\n\n**Command Execution (WHITELISTED ONLY)**:\n- Allowed: grep, sed, awk, find, cat, head, tail, sort, uniq, wc, ls, echo, cut, tr, cp, mv, rm, mkdir, rmdir, pwd, df, free, ps, top, du, whoami, date, uname\n- **Git reads allowed**: git status, git log, git diff, git show, git branch, git reflog, git rev-parse, git shortlog, git describe\n- **Git actions FORBIDDEN**: git add, git commit, git push, git checkout, git reset, git rm, etc.\n- Use for searching code, reading git context, running tests/lint\n\n**Todo Management**:\n- `todo_create`: Add new task\n- `todo_read`: View all todos or specific one by ID\n- `todo_update`: Update task or change status (pending/in_progress/completed)\n- `todo_delete`: Remove completed or cancelled tasks\n\n## Important Rules\n\n1. **NEVER commit or stage changes**: Only git reads are allowed.\n2. **Check for tests**: Always look for test files and run them when appropriate.\n3. **Reference code locations**: Use format `file_path:line_number`.\n4. **Security**: Never generate or guess URLs. Only use URLs from local files.\n5. **Refuse malicious code**: If code appears malicious, refuse to work on it.\n6. **Ask clarifications**: When intent is unclear, ask questions.\n7. **Path handling**: Relative paths resolve against CodingDir. Use `/absolute/path` to bypass.\n\n## Response Style\n- Be direct and concise\n- One word answers are best when appropriate\n- Avoid: \"The answer is...\", \"Here is...\"\n- Use markdown for formatting\n- No emojis unless user explicitly requests",
"role": "CodingAssistant",
"filepath": "sysprompts/coding_assistant.json",
"first_msg": "Hello! I'm your coding assistant. I can help you with software engineering tasks like writing code, debugging, refactoring, and exploring codebases. I work best when you give me specific tasks, and for complex work, I'll create a todo list to track my progress. What would you like to work on?"
diff --git a/tables.go b/tables.go
index 086bdf7..a69bb1a 100644
--- a/tables.go
+++ b/tables.go
@@ -820,7 +820,7 @@ func makeFilePicker() *tview.Flex {
}
// Create UI elements
listView := tview.NewList()
- listView.SetBorder(true).SetTitle("Files & Directories").SetTitleAlign(tview.AlignLeft)
+ listView.SetBorder(true).SetTitle("Files & Directories [c: set CodingDir]").SetTitleAlign(tview.AlignLeft)
// Status view for selected file information
statusView := tview.NewTextView()
statusView.SetBorder(true).SetTitle("Selected File").SetTitleAlign(tview.AlignLeft)
@@ -1032,6 +1032,37 @@ func makeFilePicker() *tview.Flex {
refreshList(currentDisplayDir, "")
return nil
}
+ if event.Rune() == 'c' {
+ // Set CodingDir to current directory
+ itemIndex := listView.GetCurrentItem()
+ if itemIndex >= 0 && itemIndex < listView.GetItemCount() {
+ itemText, _ := listView.GetItemText(itemIndex)
+ // Get the actual directory path
+ var targetDir string
+ if strings.HasPrefix(itemText, "Exit") || strings.HasPrefix(itemText, "Select this directory") {
+ targetDir = currentDisplayDir
+ } else {
+ actualItemName := itemText
+ if bracketPos := strings.Index(itemText, " ["); bracketPos != -1 {
+ actualItemName = itemText[:bracketPos]
+ }
+ if strings.HasPrefix(actualItemName, "../") {
+ targetDir = path.Dir(currentDisplayDir)
+ } else if strings.HasSuffix(actualItemName, "/") {
+ dirName := strings.TrimSuffix(actualItemName, "/")
+ targetDir = path.Join(currentDisplayDir, dirName)
+ } else {
+ targetDir = currentDisplayDir
+ }
+ }
+ cfg.CodingDir = targetDir
+ if err := notifyUser("CodingDir", "Set to: "+targetDir); err != nil {
+ logger.Error("failed to notify user", "error", err)
+ }
+ pages.RemovePage(filePickerPage)
+ return nil
+ }
+ }
case tcell.KeyEnter:
// Get the currently highlighted item in the list
itemIndex := listView.GetCurrentItem()
diff --git a/tools.go b/tools.go
index dbf1f89..dcf0632 100644
--- a/tools.go
+++ b/tools.go
@@ -9,6 +9,7 @@ import (
"io"
"os"
"os/exec"
+ "path/filepath"
"regexp"
"strconv"
"strings"
@@ -377,6 +378,8 @@ func fileCreate(args map[string]string) []byte {
return []byte(msg)
}
+ path = resolvePath(path)
+
content, ok := args["content"]
if !ok {
content = ""
@@ -400,6 +403,8 @@ func fileRead(args map[string]string) []byte {
return []byte(msg)
}
+ path = resolvePath(path)
+
content, err := readStringFromFile(path)
if err != nil {
msg := "failed to read file; error: " + err.Error()
@@ -428,6 +433,7 @@ func fileWrite(args map[string]string) []byte {
logger.Error(msg)
return []byte(msg)
}
+ path = resolvePath(path)
content, ok := args["content"]
if !ok {
content = ""
@@ -448,6 +454,7 @@ func fileWriteAppend(args map[string]string) []byte {
logger.Error(msg)
return []byte(msg)
}
+ path = resolvePath(path)
content, ok := args["content"]
if !ok {
content = ""
@@ -469,6 +476,8 @@ func fileDelete(args map[string]string) []byte {
return []byte(msg)
}
+ path = resolvePath(path)
+
if err := removeFile(path); err != nil {
msg := "failed to delete file; error: " + err.Error()
logger.Error(msg)
@@ -486,6 +495,7 @@ func fileMove(args map[string]string) []byte {
logger.Error(msg)
return []byte(msg)
}
+ src = resolvePath(src)
dst, ok := args["dst"]
if !ok || dst == "" {
@@ -493,6 +503,7 @@ func fileMove(args map[string]string) []byte {
logger.Error(msg)
return []byte(msg)
}
+ dst = resolvePath(dst)
if err := moveFile(src, dst); err != nil {
msg := "failed to move file; error: " + err.Error()
@@ -511,6 +522,7 @@ func fileCopy(args map[string]string) []byte {
logger.Error(msg)
return []byte(msg)
}
+ src = resolvePath(src)
dst, ok := args["dst"]
if !ok || dst == "" {
@@ -518,6 +530,7 @@ func fileCopy(args map[string]string) []byte {
logger.Error(msg)
return []byte(msg)
}
+ dst = resolvePath(dst)
if err := copyFile(src, dst); err != nil {
msg := "failed to copy file; error: " + err.Error()
@@ -535,6 +548,8 @@ func fileList(args map[string]string) []byte {
path = "." // default to current directory
}
+ path = resolvePath(path)
+
files, err := listDirectory(path)
if err != nil {
msg := "failed to list directory; error: " + err.Error()
@@ -558,6 +573,13 @@ func fileList(args map[string]string) []byte {
// Helper functions for file operations
+func resolvePath(p string) string {
+ if filepath.IsAbs(p) {
+ return p
+ }
+ return filepath.Join(cfg.CodingDir, p)
+}
+
func readStringFromFile(filename string) (string, error) {
data, err := os.ReadFile(filename)
if err != nil {
diff --git a/tui.go b/tui.go
index 147d35c..62cdfad 100644
--- a/tui.go
+++ b/tui.go
@@ -76,6 +76,7 @@ var (
[yellow]Ctrl+c[white]: close programm
[yellow]Ctrl+n[white]: start a new chat
[yellow]Ctrl+o[white]: open image file picker
+[yellow]c[white]: (in file picker) set current dir as CodingDir
[yellow]Ctrl+p[white]: props edit form (min-p, dry, etc.)
[yellow]Ctrl+v[white]: show API link selection popup to choose current API
[yellow]Ctrl+r[white]: start/stop recording from your microphone (needs stt server or whisper binary)