Skip to main content

ripwire-graph-query

A call-graph question the fixed verbs can't phrase — 'which high-complexity functions can reach X?', 'what has 10+ callers in src/?', 'untested symbols within one hop of main'. --graph-query: a small closed expression language — kind, complexity, fan-in, tested filters; a file or cluster; bounded hops; and/or/not.

설치로 이동

소스 정보

저장소
redhat-et/ripwire
최근 소스 활동
2026년 9월 13일 02:43
감지된 SKILL.md 언어
영어
스타
2,312
포크
149

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
ripwire-graph-query
description
A call-graph question the fixed verbs can't phrase — 'which high-complexity functions can reach X?', 'what has 10+ callers in src/?', 'untested symbols within one hop of main'. --graph-query: a small closed expression language — kind, complexity, fan-in, tested filters; a file or cluster; bounded hops; and/or/not.
allowed-tools
Bash, Read
# Graph queries with ripwire > One-hop questions have cheaper verbs — **ripwire-navigate** (`--callers`, `--callees`, `--uses`, > `--path`, `--impact`). Reach for `--graph-query` only when you need to COMBINE conditions. > Repo-wide architecture health (not one query) → **ripwire-layers**. ## Planning a refactor: find the cluster AND its blast radius The refactor-planning question is always two conditions at once — "what's messy" AND "what would touching it affect" — which is exactly what a single fixed verb can't phrase: ``` # the refactor short-list: high-complexity functions in the target area ripwire <dir> --graph-query='and(cx(all,15),file(all,"src/"))' --legend=compact # now the blast radius: everyone who transitively calls into that cluster (≤3 hops) ripwire <dir> --graph-query='callers(and(cx(all,15),file(all,"src/")),3)' --legend=compact ``` (Verified on this repo's shape, not its exact numbers — `count=` drifts every commit: the first query returns the high-cx symbols under `src/`, each `<s t= n= p=>` (kind/name/path); the second returns the transitive caller set, typically smaller than the cluster itself because many hits are leaf-ish or call each other. Read the header's own `count=`/`shown=` on your run, don't trust a number pasted here. Narrow `file(...)` to your actual target directory before trusting the numbers.) Run the first to size the cluster, the second to size the risk — a small high-cx cluster with a huge `callers()` closure is a refactor that needs a compatibility shim or a staged rollout, not a rewrite in place; a small cluster with a small closure is safe to just rewrite. `ripwire <dir> --graph-query='EXPR' --legend=compact` evaluates a small functional expression to a deterministic, ranked node set (capped at `--top-k`, default 200). It is a fixed, closed operator set — **not** Datalog: no user rules, no unbounded recursion. ## The operators | Kind | Form | Meaning | |---|---|---| | source | `name("X")` | symbols named X (unions same-name defs) | | source | `all` | every INDEXED symbol | | filter | `kind(EXPR, K)` | keep kind K: `fn` `method` `cls` `struct` `iface` `var` `sec` | | filter | `cx(EXPR, N)` | keep cyclomatic complexity ≥ N | | filter | `fanin(EXPR, N)` | keep in-degree (caller count) ≥ N | | filter | `file(EXPR, "RE")` | keep symbols whose file path matches the ECMAScript regex RE | | closure | `callers(EXPR [, D=1])` | nodes that transitively (≤ D hops) CALL anything in EXPR | | closure | `callees(EXPR [, D=1])` | nodes transitively (≤ D hops) CALLED BY anything in EXPR | | join | `and(A, B)` / `or(A, B)` | intersection / union | | join | `not(A, B)` | difference (A minus B) | ## Verified examples (single-quote the whole expression for the shell) ``` # the functions that transitively (≤2 hops) call buildGraph ripwire <dir> --graph-query='and(callers(name("buildGraph"),2),kind(all,fn))' --legend=compact # high-complexity symbols in src/ (the refactor short-list) ripwire <dir> --graph-query='and(cx(all,15),file(all,"src/"))' --legend=compact # heavily-depended-on symbols (10+ callers) — the de-facto API surface ripwire <dir> --graph-query='fanin(all,10)' --legend=compact # everything main can reach within 2 hops ripwire <dir> --graph-query='callees(name("main"),2)' --legend=compact # functions NOT reachable from main's callers (difference) ripwire <dir> --graph-query='not(kind(all,fn),callers(name("main")))' --legend=compact # a two-symbol watchlist ripwire <dir> --graph-query='or(name("buildGraph"),name("rankGraph"))' --legend=compact ``` ## Calibration - Results come back **importance-ranked and capped at top-k** — `count=` vs `shown=` in the header tells you if the cap bit; narrow the query or raise `--top-k`. - Closures walk the same **name-based** edges as `--callers` — dynamic dispatch / callbacks / macros can be missing, and `amb` edges were guessed. Verify in source when which-target matters. - A malformed expression (unknown operator, bad `file()` regex) reports the parse error and yields nothing — it never half-answers.
GitHub에서 보기