Skip to content

Tier A/B api polish: enclosing-scope context, caller_of/callee_of, filters - #46

Merged
Kristof Roomp (mcroomp) merged 2 commits into
mainfrom
tier-a-and-b
May 20, 2026
Merged

Kristof Roomp (mcroomp) merged 2 commits into
mainfrom
tier-a-and-b

Conversation

@mcroomp

Copy link
Copy Markdown
Contributor

Summary

API enhancements driven by friction notes from a full stsom + absblobstore code-trace session. All changes are AST-side or daemon-side; no schema changes, no re-index required.

Tier A -- workflow / output polish

  • body promoted to query_codebase: returns full source of every matching declaration across the codebase in one call (was 3 round-trips).
  • Enclosing-scope prefix on every pattern-mode hit (calls/uses/casts/accesses_of/accesses_on): each row starts with [in TypeName.MemberName] -- collapses the common "wait, which class/method is this in?" follow-up.
  • head_lines argument on body and declarations include_body=True: truncate each body to first N lines with a ... +K more lines tail.
  • Compact tier-3 follow-up suggestions (~80 chars saved per capped file).

Tier B -- new modes and filters

  • var_type promoted to query_codebase: resolved type of every occurrence of NAME across the codebase.
  • New caller_of METHOD mode: groups call sites by enclosing caller ([in TypeName.MemberName] (N call sites)). 53 hits -> ~18 unique-caller rows in the sample run.
  • New callee_of METHOD mode: walks the named method's body and emits one row per distinct callee with invocation counts. Constructor calls reported as T (N invocations, ctor).
  • enclosing_method= / enclosing_class= filters on every pattern mode (calls/uses/casts/accesses_of/accesses_on/all_refs). Compose as logical AND.

Daemon

  • _run_query catches ValueError from per-file AST dispatch so mixed-language codebase queries don't crash when one file's language doesn't implement the mode.

Refactor (second commit)

  • Extracts _iter_call_sites shared by q_calls / q_caller_of -- removes the text-prefix re-parsing that previously coupled the two modes.
  • Extracts _member_decl_name_node -- the field/event_field unwrap was duplicated.
  • Replaces the _filter_by_enclosing line-map post-pass with native enclosing_method / enclosing_class kwargs on each q_uses sub-helper. One AST walk instead of two.

Tests: +44 new cases. Full suite (1131 tests) green; 10x stability sweep clean.

Docs: CLAUDE.md mode table updated with new body semantics, caller_of/callee_of rows, var_type codebase-wide note, and the enclosing-scope-filter section. MCP tool docstrings updated.

Test plan

  • pytest tests/ query/tests/ -v -- 1131 passed
  • 10x full-suite stability sweep clean
  • Manual: caller_of and callee_of against real stsom files via MCP
  • Manual: body codebase-wide with head_lines truncation
  • Manual: enclosing-scope filter composes with calls and uses

Kristof Roomp and others added 2 commits May 18, 2026 16:16
Two tiers of API enhancements from the friction notes after using the
tool through a full stsom + absblobstore code-trace session. All changes
are AST-side or daemon-side; no schema changes, no re-index required.

TIER A -- workflow / output polish

* ``body`` promoted to ``query_codebase``: returns the full source of
  every matching declaration across the codebase in one call, instead
  of forcing the agent through three round-trips (find declarations ->
  find implementor types -> body per file). Same compact ASCII header
  format that ``query_single_file body`` already used. Other languages
  silently skip when they don't implement ``body``.

* Enclosing-scope prefix on every pattern-mode hit
  (``calls`` / ``uses`` / ``casts`` / ``accesses_of`` / ``accesses_on``):
  each result row now starts with ``[in TypeName.MemberName] ``
  (or ``[in TypeName] `` at type-level). Collapses the common
  "wait, which class/method is this in?" follow-up that previously
  needed a separate ``at LINE:COL`` query.

* ``head_lines`` argument on ``body`` and
  ``declarations include_body=True``: truncates each emitted body to
  the first N source lines, with a ``... +K more lines`` tail marker.
  Cheap token-saver when scanning many bodies.

* Compact tier-3 follow-up suggestions: the verbose per-file
  ``query_single_file("X", "Y", file="path")  # N total hits`` lines
  collapsed to ``[+K capped] path`` form, with one shared reminder at
  the top of the suggestion block. ~80 chars saved per capped file.

TIER B -- new modes and filters

* ``var_type`` promoted to ``query_codebase``: report resolved type of
  every occurrence of NAME across the codebase, not just one file.

* New ``caller_of METHOD`` mode: like ``calls``, but groups call sites
  by the enclosing caller (``[in TypeName.MemberName]  (N call sites)``).
  Collapses 53 call-site hits into ~18 unique-caller rows.

* New ``callee_of METHOD`` mode: walk the body of the named method
  and return one row per distinct callee with invocation counts.
  Constructor calls (``new T()``) are reported as
  ``T  (N invocations, ctor)``. Useful for "what does this method
  depend on" analysis without reading the full body.

* ``enclosing_method=`` and ``enclosing_class=`` filters on every
  pattern mode (``calls``/``uses``/``casts``/``accesses_of``/
  ``accesses_on``/``all_refs``). Compose as logical AND. Lets the agent
  ask "find calls to Save inside methods named WriteBack of class
  OrderProcessor" in one query instead of post-filtering.

DAEMON

* ``_run_query`` now catches ``ValueError`` from per-file AST dispatch
  so codebase-wide queries with mixed-language file sets don't crash
  when one of the files' languages doesn't implement the mode.

TESTS: +44 new cases. All 1131 tests pass; 10x full-suite stability
sweep clean.

DOCS: CLAUDE.md mode table updated with the new ``body`` semantics,
``caller_of``/``callee_of`` rows, ``var_type`` codebase-wide note,
and a new enclosing-scope-filter section. MCP tool docstrings updated
with the new modes and arguments.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three small cleanups in query/cs.py, no behavior change. All 469 query
tests pass.

* Extract _iter_call_sites: shared by q_calls and q_caller_of so both
  modes have identical matching semantics. q_caller_of previously
  re-parsed q_calls' "[in TypeName.MemberName] " text prefix to recover
  the caller key -- now it walks the AST directly via the shared
  iterator and pulls the caller name straight from _enclosing_type_name
  / _enclosing_member_name. No format coupling between the two modes.

* Extract _member_decl_name_node: the field_declaration /
  event_field_declaration unwrap (name lives inside a nested
  variable_declarator) was duplicated in _enclosing_member_name and the
  now-removed _filter_by_enclosing. One helper, one rule.

* Inline enclosing-scope filtering in each q_uses sub-helper instead of
  the _filter_by_enclosing line-map post-pass. _q_field_type /
  _q_param_type / _q_return_type / _q_local_type / _q_base_uses now
  take enclosing_method / enclosing_class kwargs and skip
  non-matching nodes during their own walk. Removes the second AST
  pass that built line -> (type, member) maps for every call. Docstring
  on q_uses notes that declaration-level kinds (field/param/return/
  base) drop every row when enclosing_method is set -- the decl node
  has no enclosing method by definition.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mcroomp
Kristof Roomp (mcroomp) merged commit 2480d3f into main May 20, 2026
7 checks passed
@mcroomp
Kristof Roomp (mcroomp) deleted the tier-a-and-b branch September 24, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant