Skip to content

aft_zoom: address nested JSON paths (a.b.c, arr[0]) #185

Description

@iceteaSA

JSON already outlines and zooms — the gap is only that aft_zoom can't reach a key below the top level.

Checked against docs/v0.49-unified-tool-surface-inventory.json on current main:

aft_outline(target: "…inventory.json")
  → var $schema 2:2
    var registration_profile_manifest 236:325
    var shared_tool_inventory 326:357
    …

aft_zoom(symbols: "stable_ids")                                    → works, returns the subtree
aft_zoom(symbols: "host_only_allowlist")                           → symbol not found
aft_zoom(symbols: "registration_profile_manifest.host_only_allowlist")
  → symbol not found, did you mean: [registration_profile_manifest]

host_only_allowlist is nested inside registration_profile_manifest. The only way to read it today is zooming the parent and eating all 90 lines, or reading the file whole — which is what the outline/zoom pair exists to avoid. Deep config files are where the token savings would be largest, and they're exactly where it doesn't reach.

The error message already suggests the parent, so the lookup knows the path is partially valid.

Suggested shape

Dotted and indexed path segments in aft_zoom's symbols, for JSON and JSONC:

aft_zoom(symbols: "registration_profile_manifest.host_only_allowlist")
aft_zoom(symbols: "checked_sources[3]")

tree-sitter-json is already a dependency (0.24), so the parse side is in place. A depth parameter on aft_outline would pair well — the current output is top-level only, and one level down is often what you need to pick a path.

Two things deliberately left out: a separate json tool would duplicate what aft_outline and aft_zoom already do for this file type, and a jq passthrough would add an external binary dependency for something a path expression covers.

Worth a line in aft_gather's description too, if this lands: config and JSON targets have no call graph, so gather is the wrong tool there and outline/zoom is the right one. Agents currently have to learn that by getting a thin pack back.

We're happy to write the PR — say the word and we'll pick up the path-parsing and the tests. Also fine to defer if you'd rather shape the API first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions