Feature: Resource CLI tree, inspect, link-child, and unlink-child commands As a CleverAgents user I want to view resource trees, inspect resources, and manage DAG edges via the CLI So that I can navigate and manipulate resource hierarchies Background: Given a fresh resource tree test registry # ---- Resource Tree ---- Scenario: Tree of a resource with no children Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/root-repo" at "/tmp/root" When I display resource tree for "local/root-repo" Then the tree output should contain "local/root-repo" And the tree output should contain "git-checkout" Scenario: Tree of a resource with children shows hierarchy Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/parent-repo" at "/tmp/parent" And a resource tree resource "fs-directory" named "local/child-dir" at "/tmp/child" And resource tree child "local/child-dir" is linked to parent "local/parent-repo" When I display resource tree for "local/parent-repo" Then the tree output should contain "local/parent-repo" And the tree output should contain "local/child-dir" Scenario: Tree with depth limit of 1 Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/deep-root" at "/tmp/deep" And a resource tree resource "fs-directory" named "local/deep-child" at "/tmp/dc" And a resource tree resource "fs-directory" named "local/deep-grandchild" at "/tmp/dgc" And resource tree child "local/deep-child" is linked to parent "local/deep-root" And resource tree child "local/deep-grandchild" is linked to parent "local/deep-child" When I display resource tree depth-limited to 1 for "local/deep-root" Then the tree output should contain "local/deep-child" And the tree output should not contain "local/deep-grandchild" Scenario: Tree with type filter Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/filter-root" at "/tmp/fr" And a resource tree resource "fs-directory" named "local/filter-dir" at "/tmp/fd" And resource tree child "local/filter-dir" is linked to parent "local/filter-root" When I display resource tree type-filtered to "fs-directory" for "local/filter-root" Then the tree output should contain "local/filter-dir" Scenario: Tree in JSON format Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/json-tree" at "/tmp/jt" When I display resource tree as "json" for "local/json-tree" Then the tree output should be valid JSON Scenario: Tree of non-existent resource fails When I display resource tree for "nonexistent-resource" Then the tree command should fail And the tree output should contain "not found" # ---- Deterministic ordering ---- Scenario: Tree children are sorted by name Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/sort-root" at "/tmp/sr" And a resource tree resource "fs-directory" named "local/z-last" at "/tmp/zl" And a resource tree resource "fs-directory" named "local/a-first" at "/tmp/af" And resource tree child "local/z-last" is linked to parent "local/sort-root" And resource tree child "local/a-first" is linked to parent "local/sort-root" When I display resource tree for "local/sort-root" Then the tree output should show "local/a-first" before "local/z-last" # ---- Resource Inspect ---- Scenario: Inspect a resource shows details Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/inspect-repo" at "/tmp/ir" When I run basic inspect on "local/inspect-repo" Then the tree output should contain "local/inspect-repo" And the tree output should contain "git-checkout" Scenario: Inspect with --tree shows children Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/inspect-parent" at "/tmp/ip" And a resource tree resource "fs-directory" named "local/inspect-child" at "/tmp/ic" And resource tree child "local/inspect-child" is linked to parent "local/inspect-parent" When I run inspect with subtree on "local/inspect-parent" Then the tree output should contain "local/inspect-child" Scenario: Inspect with --tree and no children Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/no-children" at "/tmp/nc" When I run inspect with subtree on "local/no-children" Then the tree output should contain "no children" Scenario: Inspect with --file for existing file Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/file-repo" at a temp directory And a temp file "hello.txt" with content "Hello World" When I run inspect with file "hello.txt" on "local/file-repo" Then the tree output should contain "Hello World" Scenario: Inspect with --file for missing file Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/no-file" at "/tmp/nf" When I run inspect with file "nonexistent.txt" on "local/no-file" Then the tree output should contain "not found" Scenario: Inspect in JSON format Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/json-inspect" at "/tmp/ji" When I run inspect formatted as "json" on "local/json-inspect" Then the tree output should be valid JSON Scenario: Inspect non-existent resource fails When I run basic inspect on "nonexistent-resource" Then the tree command should fail And the tree output should contain "not found" # ---- Resource link-child ---- Scenario: Link child successfully Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/link-parent" at "/tmp/lp" And a resource tree resource "fs-directory" named "local/link-child" at "/tmp/lc" When I link DAG child "local/link-child" to parent "local/link-parent" Then the tree output should contain "Linked" Scenario: Link child in JSON format Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/json-parent" at "/tmp/jp" And a resource tree resource "fs-directory" named "local/json-child" at "/tmp/jc" When I link as "json" DAG child "local/json-child" to parent "local/json-parent" Then the tree output should be valid JSON And the tree output should contain "linked" Scenario: Link child with non-existent parent fails Given resource tree built-in types are bootstrapped And a resource tree resource "fs-directory" named "local/orphan" at "/tmp/orph" When I link DAG child "local/orphan" to parent "nonexistent-parent" Then the tree command should fail And the tree output should contain "not found" Scenario: Link child with non-existent child fails Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/lonely-parent" at "/tmp/lonely" When I link DAG child "nonexistent-child" to parent "local/lonely-parent" Then the tree command should fail And the tree output should contain "not found" Scenario: Duplicate link fails Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/dup-parent" at "/tmp/dp" And a resource tree resource "fs-directory" named "local/dup-child" at "/tmp/dpc" And resource tree child "local/dup-child" is linked to parent "local/dup-parent" When I link DAG child "local/dup-child" to parent "local/dup-parent" Then the tree command should fail And the tree output should contain "already exists" Scenario: Cycle detection rejects link Given resource tree built-in types are bootstrapped And a resource tree resource "fs-directory" named "local/cyc-a" at "/tmp/ca" And a resource tree resource "fs-directory" named "local/cyc-b" at "/tmp/cb" And resource tree child "local/cyc-b" is linked to parent "local/cyc-a" When I link DAG child "local/cyc-a" to parent "local/cyc-b" Then the tree command should fail And the tree output should contain "ycle" # ---- Resource unlink-child ---- Scenario: Unlink child successfully Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/unlink-parent" at "/tmp/up" And a resource tree resource "fs-directory" named "local/unlink-child" at "/tmp/uc" And resource tree child "local/unlink-child" is linked to parent "local/unlink-parent" When I unlink DAG child "local/unlink-child" from parent "local/unlink-parent" confirmed Then the tree output should contain "Unlinked" Scenario: Unlink child in JSON format Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/json-unlp" at "/tmp/jul" And a resource tree resource "fs-directory" named "local/json-unlc" at "/tmp/juc" And resource tree child "local/json-unlc" is linked to parent "local/json-unlp" When I unlink as "json" DAG child "local/json-unlc" from parent "local/json-unlp" confirmed Then the tree output should be valid JSON And the tree output should contain "unlinked" Scenario: Unlink non-existent link fails Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/nolink-parent" at "/tmp/nlp" And a resource tree resource "fs-directory" named "local/nolink-child" at "/tmp/nlc" When I unlink DAG child "local/nolink-child" from parent "local/nolink-parent" confirmed Then the tree command should fail And the tree output should contain "not found" Scenario: Unlink aborted without yes flag Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/abort-parent" at "/tmp/ap" And a resource tree resource "fs-directory" named "local/abort-child" at "/tmp/ac" And resource tree child "local/abort-child" is linked to parent "local/abort-parent" When I unlink DAG child "local/abort-child" from parent "local/abort-parent" declined Then the tree command should fail # ---- Self-link rejection ---- Scenario: Link child to itself is rejected Given resource tree built-in types are bootstrapped And a resource tree resource "fs-directory" named "local/self-link" at "/tmp/sl" When I link DAG child "local/self-link" to parent "local/self-link" Then the tree command should fail And the tree output should contain "itself" # ---- get_children service method ---- Scenario: Service get_children returns children sorted by name Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/gc-parent" at "/tmp/gcp" And a resource tree resource "fs-directory" named "local/gc-z-child" at "/tmp/gcz" And a resource tree resource "fs-directory" named "local/gc-a-child" at "/tmp/gca" And resource tree child "local/gc-z-child" is linked to parent "local/gc-parent" And resource tree child "local/gc-a-child" is linked to parent "local/gc-parent" When I get children of resource "local/gc-parent" Then the children list should have 2 items And the first child name should be "local/gc-a-child" Scenario: Service get_children returns auto-discovered children for directory Given resource tree built-in types are bootstrapped And a seeded directory exists at "/tmp/gcl" And a resource tree resource "fs-directory" named "local/gc-leaf" at "/tmp/gcl" When I get children of resource "local/gc-leaf" Then the children list should have at least 1 child # ---- Inspect with no properties ---- Scenario: Inspect resource with no properties shows none Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/noprops" at "/tmp/np" with no properties When I run basic inspect on "local/noprops" Then the tree output should contain "none" # ---- File read edge cases ---- Scenario: Inspect file on resource with no location shows no-location message Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/noloc" with no location When I run inspect with file "test.txt" on "local/noloc" Then the tree output should contain "no location" Scenario: Inspect file that cannot be read shows error message Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/badfile" at a temp directory And a temp file that is unreadable named "binary.dat" When I run inspect with file "binary.dat" on "local/badfile" Then the tree output should contain "error reading" # ---- CleverAgentsError catch blocks in CLI ---- Scenario: Tree command handles generic CleverAgentsError Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/tree-err" at "/tmp/te" When I display resource tree for "local/tree-err" with a service error Then the tree command should fail And the tree output should contain "Error" Scenario: Inspect command handles generic CleverAgentsError Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/inspect-err" at "/tmp/ie" When I run inspect on "local/inspect-err" with a service error Then the tree command should fail And the tree output should contain "Error" Scenario: Link-child command handles generic CleverAgentsError Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/link-err-p" at "/tmp/lep" And a resource tree resource "fs-directory" named "local/link-err-c" at "/tmp/lec" When I link DAG child "local/link-err-c" to parent "local/link-err-p" with a service error Then the tree command should fail And the tree output should contain "Error" Scenario: Unlink-child command handles generic CleverAgentsError Given resource tree built-in types are bootstrapped And a resource tree resource "git-checkout" named "local/unlink-err-p" at "/tmp/uep" And a resource tree resource "fs-directory" named "local/unlink-err-c" at "/tmp/uec" And resource tree child "local/unlink-err-c" is linked to parent "local/unlink-err-p" When I unlink DAG child "local/unlink-err-c" from parent "local/unlink-err-p" with a service error Then the tree command should fail And the tree output should contain "Error"