Feature: Skill Search and Directory Tools
  As a developer
  I want skill-level directory listing and search tools
  So that agents can list directories, match files by glob, and
  search file contents with regex

  # ---- ListDir ----

  Scenario: ListDir lists directory contents
    Given a skill search sandbox directory
    And a search sandbox file "a.txt" with content "a"
    And a search sandbox file "b.py" with content "b"
    When I list-dir "." in the search sandbox
    Then the search tool result should be successful
    And the search output "total" should be greater than or equal to 2
    And the search output "truncated" should be boolean false

  Scenario: ListDir with type filter for files only
    Given a skill search sandbox directory
    And a search sandbox file "file.txt" with content "content"
    And a search sandbox subdirectory "subdir"
    When I list-dir-typed "." with type_filter "files"
    Then the search tool result should be successful
    And all search entries should not be directories

  Scenario: ListDir with type filter for dirs only
    Given a skill search sandbox directory
    And a search sandbox file "file.txt" with content "content"
    And a search sandbox subdirectory "subdir"
    When I list-dir-typed "." with type_filter "dirs"
    Then the search tool result should be successful
    And all search entries should be directories

  Scenario: ListDir with ignore patterns
    Given a skill search sandbox directory
    And a search sandbox file "keep.txt" with content "keep"
    And a search sandbox file "ignore.log" with content "ignore"
    When I list-dir-ignoring "." ignoring "*.log"
    Then the search tool result should be successful
    And no search entry should have name "ignore.log"

  Scenario: ListDir with size limit
    Given a skill search sandbox directory
    And a search sandbox file "1.txt" with content "one"
    And a search sandbox file "2.txt" with content "two"
    And a search sandbox file "3.txt" with content "three"
    When I list-dir-limited "." with limit 2
    Then the search tool result should be successful
    And the search output "truncated" should be boolean true
    And the search output "total" should equal 2

  Scenario: ListDir on non-directory raises error
    Given a skill search sandbox directory
    And a search sandbox file "notadir.txt" with content "x"
    When I list-dir "notadir.txt" in the search sandbox
    Then the search tool result should not be successful
    And the search tool error should mention "not a directory"

  Scenario: ListDir with invalid type_filter raises error
    Given a skill search sandbox directory
    When I list-dir-typed "." with type_filter "invalid"
    Then the search tool result should not be successful
    And the search tool error should mention "Invalid type_filter"

  # ---- Glob ----

  Scenario: Glob matches files by pattern
    Given a skill search sandbox directory
    And a search sandbox file "main.py" with content "code"
    And a search sandbox file "test.py" with content "test"
    And a search sandbox file "readme.md" with content "docs"
    When I glob-match "." for "*.py"
    Then the search tool result should be successful
    And the search glob total should be 2

  Scenario: Glob with exclude patterns
    Given a skill search sandbox directory
    And a search sandbox file "main.py" with content "code"
    And a search sandbox file "test.py" with content "test"
    When I glob-exclude "." for "*.py" excluding "test*"
    Then the search tool result should be successful
    And the search glob total should be 1
    And no search match should have name "test.py"

  Scenario: Glob with include filter
    Given a skill search sandbox directory
    And a search sandbox file "main.py" with content "code"
    And a search sandbox file "test.py" with content "test"
    When I glob-include "." for "*" including "*.py"
    Then the search tool result should be successful
    And the search glob total should be at least 2

  Scenario: Glob returns deterministic sorted results
    Given a skill search sandbox directory
    And a search sandbox file "c.txt" with content "c"
    And a search sandbox file "a.txt" with content "a"
    And a search sandbox file "b.txt" with content "b"
    When I glob-match "." for "*.txt"
    Then the search tool result should be successful
    And the search glob results should be sorted by name

  Scenario: Glob on non-directory raises error
    Given a skill search sandbox directory
    And a search sandbox file "notadir.txt" with content "x"
    When I glob-match "notadir.txt" for "*.txt"
    Then the search tool result should not be successful
    And the search tool error should mention "not a directory"

  Scenario: Glob with limit truncation
    Given a skill search sandbox directory
    And a search sandbox file "1.txt" with content "one"
    And a search sandbox file "2.txt" with content "two"
    And a search sandbox file "3.txt" with content "three"
    When I glob-limited "." for "*.txt" with limit 2
    Then the search tool result should be successful
    And the search output "truncated" should be boolean true

  # ---- Grep ----

  Scenario: Grep finds matching lines
    Given a skill search sandbox directory
    And a search sandbox file "haystack.txt" with content "needle in a haystack"
    When I grep-search "." for "needle"
    Then the search tool result should be successful
    And the search grep total should be at least 1

  Scenario: Grep with context lines
    Given a skill search sandbox directory
    And a search sandbox file "context.txt" with lines "before,match,after"
    When I grep-context "." for "match" with context 1
    Then the search tool result should be successful
    And the search grep first match should have context_before
    And the search grep first match should have context_after

  Scenario: Grep skips binary files
    Given a skill search sandbox directory
    And a search sandbox binary file "data.bin"
    And a search sandbox file "text.txt" with content "findme"
    When I grep-search "." for "findme"
    Then the search tool result should be successful
    And the search grep matches should not reference "data.bin"

  Scenario: Grep with per-file match cap
    Given a skill search sandbox directory
    And a search sandbox file "many.txt" with lines "match,match,match,match,match"
    When I grep-capped "." for "match" with per_file_cap 2
    Then the search tool result should be successful
    And the search grep total should equal 2

  Scenario: Grep with total match limit
    Given a skill search sandbox directory
    And a search sandbox file "m1.txt" with lines "hit,hit,hit"
    And a search sandbox file "m2.txt" with lines "hit,hit,hit"
    When I grep-maxed "." for "hit" with max_matches 3
    Then the search tool result should be successful
    And the search grep total should equal 3
    And the search output "truncated" should be boolean true

  Scenario: Grep with invalid regex raises error
    Given a skill search sandbox directory
    When I grep-search "." for "[invalid"
    Then the search tool result should not be successful
    And the search tool error should mention "Invalid regex"

  Scenario: Grep on non-directory raises error
    Given a skill search sandbox directory
    And a search sandbox file "notadir.txt" with content "x"
    When I grep-search "notadir.txt" for "x"
    Then the search tool result should not be successful
    And the search tool error should mention "not a directory"

  # ---- Path Traversal ----

  Scenario: Path traversal in list-dir is rejected
    Given a skill search sandbox directory
    When I list-dir "../../etc" in the search sandbox
    Then the search tool result should not be successful
    And the search tool error should mention "traversal"

  Scenario: Path traversal in glob is rejected
    Given a skill search sandbox directory
    When I glob-match "../../etc" for "*"
    Then the search tool result should not be successful
    And the search tool error should mention "traversal"

  Scenario: Path traversal in grep is rejected
    Given a skill search sandbox directory
    When I grep-search "../../etc" for "root"
    Then the search tool result should not be successful
    And the search tool error should mention "traversal"

  # ---- Read-Only Capability ----

  Scenario: ListDir has read_only capability
    Given a skill search tools registry
    Then the search tool "skill/list-dir" should have read_only capability

  Scenario: Glob has read_only capability
    Given a skill search tools registry
    Then the search tool "skill/glob" should have read_only capability

  Scenario: Grep has read_only capability
    Given a skill search tools registry
    Then the search tool "skill/grep" should have read_only capability

  # ---- Registration ----

  Scenario: Register all skill search tools
    Given a skill search tools registry
    Then the search registry should contain 3 tools
    And the search registry should contain tool "skill/list-dir"
    And the search registry should contain tool "skill/glob"
    And the search registry should contain tool "skill/grep"

  # ---- Coverage: OSError fallbacks, include patterns, directory skip ----

  Scenario: ListDir handles stat failure gracefully
    Given a skill search sandbox directory
    And a search sandbox file "statfail.txt" with content "test"
    When I execute list-dir with a stat failure mock
    Then the list-dir result should contain "statfail.txt" with size 0

  Scenario: Glob filters by include pattern
    Given a skill search sandbox directory
    And a search sandbox file "keep.txt" with content "a"
    And a search sandbox file "skip.py" with content "b"
    When I execute glob with pattern "*" and include "*.txt"
    Then the glob results should contain "keep.txt"
    And the glob results should not contain "skip.py"

  Scenario: Glob handles stat failure gracefully
    Given a skill search sandbox directory
    And a search sandbox file "globstat.txt" with content "test"
    When I execute glob with a stat failure mock and pattern "*.txt"
    Then the glob result should contain "globstat.txt" with size 0

  Scenario: Grep skips directories in rglob
    Given a skill search sandbox directory
    And a search sandbox subdirectory "subdir"
    And a search sandbox file "subdir/match.txt" with content "findme here"
    When I execute grep with pattern "findme" and include "*"
    Then the grep results should contain "match.txt"
    And the grep results should not contain a directory entry

  Scenario: Grep skips unreadable files gracefully
    Given a skill search sandbox directory
    And a search sandbox file "unreadable.txt" with content "content"
    When I execute grep with a read_text failure mock and pattern "content"
    Then the grep result should be empty
