Feature: Built-in File Tools As a developer I want built-in file operation tools So that agents can read, write, edit, delete, list, and search files safely # ---- File Read ---- Scenario: Read a file with default encoding Given a temporary sandbox directory And a file "hello.txt" with content "Hello, World!" When I execute the "builtin/file-read" tool with path "hello.txt" Then the tool result should be successful And the output "content" should be "Hello, World!" And the output "encoding" should be "utf-8" And the output "size" should be greater than 0 Scenario: Read a file with offset and limit Given a temporary sandbox directory And a file "lines.txt" with lines "line1,line2,line3,line4,line5" When I execute the "builtin/file-read" tool with path "lines.txt" offset 1 limit 2 Then the tool result should be successful And the output "content" should contain "line2" And the output "content" should contain "line3" And the output "content" should not contain "line1" # ---- File Write ---- Scenario: Write a new file Given a temporary sandbox directory When I execute the "builtin/file-write" tool with path "new.txt" and content "created" Then the tool result should be successful And the output "created" should be boolean true And the output "size" should be greater than 0 And the file "new.txt" should exist in the sandbox Scenario: Overwrite an existing file Given a temporary sandbox directory And a file "existing.txt" with content "old content" When I execute the "builtin/file-write" tool with path "existing.txt" and content "new content" Then the tool result should be successful And the output "created" should be boolean false Scenario: Write file creates parent directories Given a temporary sandbox directory When I execute the "builtin/file-write" tool with path "sub/dir/file.txt" and content "nested" Then the tool result should be successful And the file "sub/dir/file.txt" should exist in the sandbox # ---- File Edit ---- Scenario: Edit file with single replacement Given a temporary sandbox directory And a file "edit.txt" with content "foo bar foo" When I execute the "builtin/file-edit" tool replacing "foo" with "baz" Then the tool result should be successful And the output "replacements" should equal 1 Scenario: Edit file with replace_all Given a temporary sandbox directory And a file "edit.txt" with content "foo bar foo" When I execute the "builtin/file-edit" tool replacing all "foo" with "baz" Then the tool result should be successful And the output "replacements" should equal 2 Scenario: Edit file with old_text not found raises error Given a temporary sandbox directory And a file "edit.txt" with content "foo bar" When I execute the "builtin/file-edit" tool replacing "notfound" with "baz" Then the tool result should not be successful And the tool result error should mention "not found" Scenario: Edit file uses explicit encoding parameter Given a temporary sandbox directory And an encoded file "edit-enc.txt" with encoding "latin-1" and content "café" When I edit file "edit-enc.txt" replacing "café" with "naïve" specifying encoding "latin-1" Then the tool result should be successful And the output "replacements" should equal 1 Scenario: Edit file defaults to utf-8 encoding when not specified Given a temporary sandbox directory And a file "edit.txt" with content "default encoding test" When I execute the "builtin/file-edit" tool replacing "default" with "explicit" Then the tool result should be successful And the output "replacements" should equal 1 # ---- File Delete ---- Scenario: Delete an existing file Given a temporary sandbox directory And a file "delete-me.txt" with content "doomed" When I execute the "builtin/file-delete" tool with path "delete-me.txt" Then the tool result should be successful And the output "existed" should be boolean true And the file "delete-me.txt" should not exist in the sandbox Scenario: Delete a nonexistent file Given a temporary sandbox directory When I execute the "builtin/file-delete" tool with path "ghost.txt" Then the tool result should be successful And the output "existed" should be boolean false # ---- File List ---- Scenario: List directory contents Given a temporary sandbox directory And a file "a.txt" with content "a" And a file "b.py" with content "b" When I list directory "." with the file-list tool Then the tool result should be successful And the output files list should contain at least 2 entries Scenario: List directory with pattern filter Given a temporary sandbox directory And a file "a.txt" with content "a" And a file "b.py" with content "b" When I list directory "." filtering by pattern "*.txt" Then the tool result should be successful And all listed files should match pattern "*.txt" Scenario: List directory recursively Given a temporary sandbox directory And a file "sub/deep.txt" with content "deep" When I list directory "." recursively with the file-list tool Then the tool result should be successful And the output files list should contain at least 1 entries # ---- File Search ---- Scenario: Search files for pattern Given a temporary sandbox directory And a file "haystack.txt" with content "needle in a haystack" When I search directory "." for pattern "needle" Then the tool result should be successful And the search matches should contain at least 1 result Scenario: Search with max_results limit Given a temporary sandbox directory And a file "many.txt" with lines "match,match,match,match,match" When I search directory "." for pattern "match" with max_results 2 Then the tool result should be successful And the search matches should contain exactly 2 results # ---- Path Traversal Prevention ---- Scenario: Path traversal with dotdot is rejected Given a temporary sandbox directory When I execute the "builtin/file-read" tool with path "../../etc/passwd" Then the tool result should not be successful And the tool result error should mention "traversal" Scenario: Path traversal in write is rejected Given a temporary sandbox directory When I execute the "builtin/file-write" tool with path "../escape.txt" and content "evil" Then the tool result should not be successful And the tool result error should mention "traversal" Scenario: Path traversal in delete is rejected Given a temporary sandbox directory When I execute the "builtin/file-delete" tool with path "../../etc/passwd" Then the tool result should not be successful And the tool result error should mention "traversal" @tdd_issue @tdd_issue_7558 Scenario: Path traversal with sandbox name prefix collision is rejected Given a temporary sandbox directory And a sibling directory with a name that is a prefix of the sandbox name When I attempt to read a file in the sibling escape directory Then the tool result should not be successful And the tool result error should mention "traversal" # ---- ChangeSet Capture ---- Scenario: ChangeSet captures write operations Given a temporary sandbox directory And a changeset capture with plan_id "plan-001" When I write a file through changeset-wrapped tools Then the changeset should have 1 entry And the changeset entry operation should be "create" Scenario: ChangeSet captures edit operations Given a temporary sandbox directory And a file "cs-edit.txt" with content "hello world" And a changeset capture with plan_id "plan-002" When I edit a file through changeset-wrapped tools Then the changeset should have 1 entry And the changeset entry operation should be "modify" Scenario: ChangeSet captures delete operations Given a temporary sandbox directory And a file "cs-delete.txt" with content "bye" And a changeset capture with plan_id "plan-003" When I delete a file through changeset-wrapped tools Then the changeset should have 1 entry And the changeset entry operation should be "delete" Scenario: ChangeSet summary generation Given a temporary sandbox directory And a changeset capture with plan_id "plan-004" When I perform multiple changeset-tracked operations Then the changeset summary should mention the total count And the changeset summary should mention operation types Scenario: ChangeSet clear resets tracking Given a temporary sandbox directory And a changeset capture with plan_id "plan-005" When I write a file through changeset-wrapped tools And I clear the changeset Then the changeset should have 0 entries Scenario: Empty changeset summary Given a changeset capture with plan_id "plan-empty" Then the changeset summary should be "No changes recorded" # ---- Tool Registration Helper ---- Scenario: Register all file tools Given a tool registry When I register all file tools Then the registry should contain 6 tools And the registry should contain tool "builtin/file-read" And the registry should contain tool "builtin/file-write" And the registry should contain tool "builtin/file-edit" And the registry should contain tool "builtin/file-delete" And the registry should contain tool "builtin/file-list" And the registry should contain tool "builtin/file-search" Scenario: Register file tools with changeset Given a tool registry And a changeset capture with plan_id "plan-reg" When I register file tools with changeset Then the registry should contain 6 tools # ---- ChangeSet model fields ---- Scenario: ChangeSetEntry stores before and after hashes Given a temporary sandbox directory And a file "hash-test.txt" with content "original" And a changeset capture with plan_id "plan-hash" When I edit "hash-test.txt" through changeset-wrapped tools Then the changeset entry should have a before_hash And the changeset entry should have an after_hash And the before_hash and after_hash should differ Scenario: File list on non-directory raises error Given a temporary sandbox directory And a file "notadir.txt" with content "x" When I list directory "notadir.txt" with the file-list tool Then the tool result should not be successful And the tool result error should mention "not a directory" Scenario: File search on non-directory raises error Given a temporary sandbox directory And a file "notadir.txt" with content "x" When I search directory "notadir.txt" for pattern "x" Then the tool result should not be successful And the tool result error should mention "not a directory" Scenario: File search skips directories in results Given a temporary sandbox directory And a subdirectory "subdir" in the sandbox And a file "subdir/content.txt" with content "findme" When I search directory "." for pattern "findme" Then the tool result should be successful And the search matches should contain at least 1 result Scenario: ChangeSet detect_operation fallback create Given a temporary sandbox directory And a changeset capture with plan_id "plan-fallback" When I write a new file through raw changeset capture Then the changeset entry operation should be "create" Scenario: ChangeSet detect_operation fallback modify Given a temporary sandbox directory And a file "existing-cs.txt" with content "some content" And a changeset capture with plan_id "plan-modify-fallback" When I overwrite a file through raw changeset capture Then the changeset entry operation should be "modify"