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