graph-indexer 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +412 -0
- package/README.md +216 -596
- package/SECURITY.md +68 -0
- package/TRADEMARK.md +31 -0
- package/cli-ui.mjs +78 -0
- package/config.mjs +179 -28
- package/daemon-ctl.mjs +175 -0
- package/daemon-lock.mjs +69 -0
- package/embedders/python/mlx_embed_server.py +61 -0
- package/embedders/python/requirements-mlx.txt +5 -0
- package/embedders/setup-mlx.mjs +110 -0
- package/embeddings.mjs +489 -0
- package/engine/binary.mjs +399 -0
- package/{core-engine.mjs → engine/memory.mjs} +107 -440
- package/{sqlite-store.mjs → engine/sqlite.mjs} +137 -42
- package/enrichment.mjs +111 -32
- package/git-signals.mjs +248 -0
- package/indexer.mjs +151 -42
- package/init.mjs +1603 -171
- package/layout.mjs +123 -0
- package/mcp/format.mjs +61 -0
- package/mcp/tools.mjs +1157 -0
- package/mcp/topology.mjs +551 -0
- package/mcp-server.mjs +55 -24
- package/package.json +44 -13
- package/parse/extractor.mjs +617 -0
- package/parse/imports.mjs +365 -0
- package/parse/languages.mjs +89 -0
- package/parse/metadata.mjs +655 -0
- package/parse/routes.mjs +327 -0
- package/prompts/CORE.md +86 -0
- package/prompts/DOMAIN_TEMPLATE.md +46 -0
- package/prompts/INTEGRATION.md +123 -0
- package/prompts/frameworks/ANDROID.md +17 -0
- package/prompts/frameworks/ASPNET_CORE.md +19 -0
- package/prompts/frameworks/FASTAPI_DJANGO.md +19 -0
- package/prompts/frameworks/LARAVEL_SYMFONY.md +22 -0
- package/prompts/frameworks/NODE_EXPRESS_NESTJS.md +18 -0
- package/prompts/frameworks/RAILS.md +20 -0
- package/prompts/frameworks/REACT.md +20 -0
- package/prompts/frameworks/SPRING_BOOT.md +19 -0
- package/prompts/languages/BASH.md +22 -0
- package/prompts/languages/C.md +21 -0
- package/prompts/languages/CSHARP.md +24 -0
- package/prompts/languages/CSS_SCSS.md +22 -0
- package/prompts/languages/GO.md +23 -0
- package/prompts/languages/JAVA.md +23 -0
- package/prompts/languages/JAVASCRIPT_TYPESCRIPT.md +24 -0
- package/prompts/languages/KOTLIN.md +24 -0
- package/prompts/languages/PHP.md +23 -0
- package/prompts/languages/PYTHON.md +23 -0
- package/prompts/languages/RUBY.md +23 -0
- package/prompts/languages/RUST.md +21 -0
- package/prompts/languages/SWIFT.md +21 -0
- package/search-core.mjs +254 -43
- package/storage.mjs +28 -3
- package/watch-daemon.mjs +69 -23
- package/PROMPT.md +0 -182
- package/mcp-tools.mjs +0 -545
- package/parser-utils.mjs +0 -1170
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="framework" name="aspnet-core" requires="graph-indexer-core, csharp" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>ASP.NET Core (attribute routing or minimal APIs, built-in DI, EF Core data access). Loads after the csharp layer.</scope>
|
|
4
|
+
|
|
5
|
+
<critical_fact>Controller actions and endpoint handlers are invoked by the routing middleware: empty call graphs on them mean ENTRY POINT, never dead code.</critical_fact>
|
|
6
|
+
|
|
7
|
+
<rules>
|
|
8
|
+
<rule name="routes">Attribute-routed: full route = class-level [Route("api/[controller]")] PLUS method-level [HttpGet("{id}")] — both on cards; find endpoints by path fragment (exact_tokens: "/orders") or verb attribute. Minimal APIs: handlers are lambdas at the `app.MapGet(...)` registration — the registration chunk IS the handler, and they live in the Program/startup chunk.</rule>
|
|
9
|
+
<rule name="registration-is-the-binding">DI wiring is explicit code: `services.AddScoped<IOrderService, OrderService>()` in Program/Startup or extension methods. ONE exact_tokens search on the INTERFACE name surfaces the registration line and the implementing class together.</rule>
|
|
10
|
+
<rule name="graph-works-below-routing">Below routing, calls are direct: controller → service → repository edges register normally — trust get_call_graph inside project code.</rule>
|
|
11
|
+
<rule name="implicit-runners">Middleware (app.UseX / InvokeAsync), filters, hosted services (ExecuteAsync), health checks are framework-invoked — the registration site names them; never hunt for callers of InvokeAsync/ExecuteAsync.</rule>
|
|
12
|
+
<rule name="ef-data-layer">LINQ queries translate to SQL at runtime — no generated code to find. The DbContext declares the sets; entity config lives in attributes or model-builder chunks. Migration files are tool-generated snapshots — skip unless schema history is the question.</rule>
|
|
13
|
+
<rule name="config-and-messages">IOptions<T>/Configuration["Key"] bind to appsettings.json — fallback condition 3 once the consumer is located; find consumers by the options class or key string. MediatR-style buses connect sender and handler by MESSAGE TYPE — ONE exact_tokens search on the message class finds both ends.</rule>
|
|
14
|
+
<rule name="query-style">Route fragments, interface names, options/message class names are the highest-precision tokens. Cross-cutting behaviour ("where do we log request IDs") lives in middleware you can't name — search behaviourally.</rule>
|
|
15
|
+
</rules>
|
|
16
|
+
|
|
17
|
+
<playbook question="what happens on POST /orders" calls="3-4">search_code(exact_tokens: "/orders") → get_chunk_summary(controller action or Map* registration, expand_calls: true) → get_chunk_summary(the ONE service method doing the work) → answer; ONE DI-registration or middleware hop only if the question demands it.</playbook>
|
|
18
|
+
|
|
19
|
+
</environment_prompt>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="framework" name="fastapi-django" requires="graph-indexer-core, python" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Python web app: decorator-routed endpoints (FastAPI) and/or URLconf + ORM (Django). Loads after the python layer.</scope>
|
|
4
|
+
|
|
5
|
+
<critical_fact>Endpoints and views are invoked by the framework dispatcher: an empty call graph on them means ENTRY POINT, never dead code.</critical_fact>
|
|
6
|
+
|
|
7
|
+
<rules>
|
|
8
|
+
<rule name="routes">FastAPI/Flask decorator endpoints: find_routes(method, path) maps them straight to the handler chunk_id — the first move. Fall back to a path search — search_code(query: "endpoint that updates user profile", exact_tokens: "/users") — for computed paths or behavioural matching. Django URLconf is NOT covered by find_routes: views bind in a urls file, so search the path string then resolve the referenced view name — that is 2 calls, plan for it.</rule>
|
|
9
|
+
<rule name="depends-is-a-default">FastAPI dependencies are parameter DEFAULTS (`user = Depends(get_current_user)`), not calls — no edge. The endpoint's SIGNATURE enumerates its dependencies (summary is enough); resolve at most ONE dependency body.</rule>
|
|
10
|
+
<rule name="metaclass-managers">ORM model classes are rewritten by metaclasses: `Model.objects`, queryset methods, generated fields (id, *_set) have NO chunks — resolve_symbol("objects") finding nothing is CORRECT. The MODEL class declares the schema; custom managers/querysets DO exist as classes — search the manager class name when query behaviour looks non-default.</rule>
|
|
11
|
+
<rule name="cbv-mro">Class-based views inherit handlers through mixins/generic bases: the view chunk often shows only attributes. The method you seek (get, post, get_queryset, form_valid) lives on a parent — resolve ONE parent method, guided by the bases in the view's signature.</rule>
|
|
12
|
+
<rule name="schema-models">Pydantic models, serializers, forms are declarative — the class definition IS the validation. resolve_symbol("UserCreate") answers "what is validated"; imperative validation code doesn't exist, don't search for it.</rule>
|
|
13
|
+
<rule name="signals-and-tasks">Signals connect by the signal OBJECT and tasks by name/registration — no call edges. ONE exact_tokens search on the signal/task name finds both ends. Middleware lists and settings are config files — fallback condition 3 once the consuming code is located.</rule>
|
|
14
|
+
<rule name="query-style">URL fragments and signal names beat function names. For "where is this field validated/transformed", name the FIELD and behaviour ("normalize email before saving user") — model, serializer, or signal handler, one behavioural search covers all three.</rule>
|
|
15
|
+
</rules>
|
|
16
|
+
|
|
17
|
+
<playbook question="what happens on POST /orders" calls="3-4">find_routes("POST", "/orders") (FastAPI/Flask; for Django URLconf fall back to search_code(exact_tokens: "/orders")) → get_chunk(handler/view) — decorators + signature reveal deps and models → resolve_symbol(the ONE model/service it delegates to) → answer; ONE dependency/parent hop only if the question demands it.</playbook>
|
|
18
|
+
|
|
19
|
+
</environment_prompt>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="framework" name="laravel-symfony" requires="graph-indexer-core, php" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>PHP on Laravel or Symfony (container MVC, ORM, facades/attributes). Loads after the php layer — whole-class chunks, weak topology, batched class questions all apply.</scope>
|
|
4
|
+
|
|
5
|
+
<critical_fact>Controllers are invoked by the framework dispatcher: empty call graphs on controller methods mean ENTRY POINT. And because PHP `use` imports are untracked, EMPTY Deps:/Used by: mean NOTHING — usage always comes from name search, never from topology absence.</critical_fact>
|
|
6
|
+
|
|
7
|
+
<rules>
|
|
8
|
+
<rule name="eloquent-magic">Active-record models route everything through magic methods: attributes are __get/__set on the row, `User::where(...)` is __callStatic, scopes are scopeActive defs invoked as active(), relations (hasMany/belongsTo) generate accessors. The MODEL chunk's relation/scope/cast declarations ARE the API — and model chunks are SMALL, so one batched search shows several models' full relation graphs at once. Never hunt for generated method bodies.</rule>
|
|
9
|
+
<rule name="routes">Laravel routes are DSL calls in route files (`Route::get('/orders', [OrderController::class, 'index'])`) — ONE exact_tokens search of the URL fragment finds the registration; the controller class is named right there. Symfony routes are attributes on the controller method (#[Route('/orders')]) — the class chunk includes them; search the path fragment.</rule>
|
|
10
|
+
<rule name="big-controllers">A large controller (≥~200 lines) is god-class-split, so each action is its own chunk and resolve_symbol on an action name hits directly; a smaller controller stays one whole-class chunk. Either way, get_file_skeleton(its file) lists every action with line ranges in ~80 tok — THE move instead of searching method names one by one (the skeleton call replaces 3-4 searches).</rule>
|
|
11
|
+
<rule name="facades">Facade calls (Cache::get, DB::table, Log::info) are static proxies — NO edge to the implementation behind the container binding. Treat as "delegates to the named service"; resolve the underlying service ONLY when its internals are the question.</rule>
|
|
12
|
+
<rule name="container-bindings">Interface→implementation wiring lives in service providers (bind/singleton) or services config — ONE exact_tokens search on the INTERFACE name surfaces binding site and implementation together.</rule>
|
|
13
|
+
<rule name="implicit-runners">Middleware, policies, form requests, events/listeners, subscribers run implicitly around controllers. Registrations (kernel/provider/route/attributes) name them; events connect dispatch site to listeners by the EVENT CLASS NAME — ONE exact_tokens search finds both ends. Read at most ONE such body.</rule>
|
|
14
|
+
<rule name="templates">Blade/Twig templates are content, not symbols: the controller chunk's view(...)/render(...) call names the template; reading the template file is fallback condition 3.</rule>
|
|
15
|
+
<rule name="symfony-test-noise">In Symfony projects, callable-object patterns in DI can cause test-class methods (from capitalized `Tests/` directories) to escape the test filter and appear as indexed symbols. If search results include unexpected `Tests\` namespace entries, treat them as index noise and filter by file path.</rule>
|
|
16
|
+
<rule name="query-style">URL fragments, event class names, config keys are the highest-precision tokens. exact_tokens on a class name REPLACES the missing Used by: — the default usage-mapping move here.</rule>
|
|
17
|
+
</rules>
|
|
18
|
+
|
|
19
|
+
<playbook question="explain models Country, Community, Region, Location — structure, relations, where used" calls="1-2">ONE search_code(query: "Country Community Region Location", detail: "smart", top_k: 10): the four model chunks rank top with their hasMany/belongsTo/HasManyThrough lines visible — that IS the hierarchy — and the controllers/Livewire components referencing them appear in the same results. Answer structure AND usage from this single call; optional 2nd call: detail: "full" + token_budget: 3000 to quote every relation method. Four resolve_symbol calls here = budget dead.</playbook>
|
|
20
|
+
<playbook question="what happens on POST /orders" calls="3-4">search_code(exact_tokens: "/orders") → get_file_skeleton(controller file) or get_chunk_summary(controller class) for the action map → get_chunk_summary(the ONE model/service it delegates to) → answer; ONE middleware/listener/binding hop only if the question demands it.</playbook>
|
|
21
|
+
|
|
22
|
+
</environment_prompt>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="framework" name="node-express-nestjs" requires="graph-indexer-core, javascript-typescript" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Node.js backend: Express-style routing and/or NestJS-style DI. Loads after the javascript-typescript layer.</scope>
|
|
4
|
+
|
|
5
|
+
<critical_fact>HTTP handlers are invoked by the framework dispatcher: an empty call graph on a route handler means ENTRY POINT, never dead code. Request flow is reconstructed from REGISTRATION sites, not from get_call_graph.</critical_fact>
|
|
6
|
+
|
|
7
|
+
<rules>
|
|
8
|
+
<rule name="routes">find_routes(method, path) maps Express/Koa and NestJS endpoints straight to their handler chunk_id — THE first move for "what handles VERB /path", and it already joins the NestJS @Controller prefix onto the @Get path. Fall back to a PATH-STRING search — search_code(query: "user creation endpoint", exact_tokens: "/users") — only for dynamic/computed paths or behavioural matching. Express handlers are often anonymous closures in `app.get(path, ...)` — find_routes reports the registration line.</rule>
|
|
9
|
+
<rule name="middleware-order">Middleware order = REGISTRATION order. "What runs before this handler" comes from the ONE app/module setup chunk where registration happens — never by resolving every middleware. `next()` carries no edge; guards/pipes/interceptors bound via decorators are visible in summaries — read AT MOST ONE middleware body, only when its logic is the question.</rule>
|
|
10
|
+
<rule name="graph-works-below-routing">Inside project code calls are direct: controller → service → repository edges register normally, and get_call_graph("createUser") reliably finds controller call sites. Trust the graph below the routing layer.</rule>
|
|
11
|
+
<rule name="container-wiring">WHICH implementation backs an injected token is container wiring, not a call: constructor injection creates no edge. Find the binding with ONE search of the module/provider registration (exact_tokens: "UserService") — never via the constructor's call graph.</rule>
|
|
12
|
+
<rule name="lifecycle-hooks">onModuleInit-style hooks, error handlers, scheduled/cron methods, event/queue consumers have no inbound edges — the decorator in the summary says WHO invokes them; don't hunt for callers.</rule>
|
|
13
|
+
<rule name="query-style">Path strings beat handler names (routes rename rarely, handlers often). Cross-cutting behaviour ("where do we attach the request ID") lives in middleware whose name you can't guess — search behaviourally.</rule>
|
|
14
|
+
</rules>
|
|
15
|
+
|
|
16
|
+
<playbook question="what happens on POST /orders" calls="3-4">find_routes("POST", "/orders") → get_chunk(handler chunk_id) → get_chunk_summary(the service it calls, expand_calls: true) → answer; ONE middleware/guard chunk only if the question is about it.</playbook>
|
|
17
|
+
|
|
18
|
+
</environment_prompt>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="framework" name="rails" requires="graph-indexer-core, ruby" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Ruby on Rails (convention-over-configuration MVC, ActiveRecord). Loads after the ruby layer — weak require topology applies.</scope>
|
|
4
|
+
|
|
5
|
+
<critical_fact>Rails wires almost everything BY NAMING CONVENTION, not by calls: router → controller action, controller → view template, model ↔ table. Most "who calls this" questions are answered by the convention itself — spend budget confirming the convention's endpoints, never searching for explicit wiring that doesn't exist.</critical_fact>
|
|
6
|
+
|
|
7
|
+
<rules>
|
|
8
|
+
<rule name="routes">Routes are DSL calls in config/routes.rb (`resources :orders`): search the URL fragment or resource name; the controller is `<Resource>sController`, the action the conventional method (index, show, create...). Controller actions are framework-invoked ENTRY POINTS — empty call graphs are normal. The rendered view matches the action name unless a render/redirect_to in the chunk overrides it.</rule>
|
|
9
|
+
<rule name="generated-methods">Associations/macros GENERATE the API at runtime: `has_many :orders` creates orders/build_order/...; attr/enum/scope macros likewise; dynamic finders (find_by_email) are metaprogrammed. NONE have chunks — the macro line in the model chunk IS the definition. Decode macros; never hunt for generated bodies.</rule>
|
|
10
|
+
<rule name="declarative-callbacks">`before_save :normalize`, `validates :email` are DECLARATIVE: the model chunk's macro lines say WHAT runs and WHEN. before_action filter chains are declared at the top of the controller chunk. Resolve at most the ONE callback/filter method whose logic is the question.</rule>
|
|
11
|
+
<rule name="concerns">Behaviour mixed in via `include SomeConcern` lives in the concern's module chunk (app/models/concerns, app/controllers/concerns) — ruby mixin rule applies, ONE module hop max.</rule>
|
|
12
|
+
<rule name="jobs-mailers">Jobs (perform_later), mailers (deliver_later), subscribers connect enqueue site to handler by CLASS NAME — ONE exact_tokens search on the class name finds both ends.</rule>
|
|
13
|
+
<rule name="non-code-config">config/*.yml, locales, credentials, db/schema.rb are data/config — fallback condition 3 once the consuming code is located.</rule>
|
|
14
|
+
<rule name="query-style">URL fragments, route helper names (order_path), macro symbols (:before_save, :orders) are the highest-precision tokens. For "where does X get validated/transformed", name the FIELD and behaviour — validation macro, callback, or form object, one behavioural search covers all.</rule>
|
|
15
|
+
</rules>
|
|
16
|
+
|
|
17
|
+
<playbook question="explain models A, B, C (and where used)" calls="1-2">ONE batched search — the macro lines (has_many, validates, scope) in the smart bodies ARE the schema and behaviour; consumers (controllers, jobs) surface in the same results because require topology is absent. Never one call per model.</playbook>
|
|
18
|
+
<playbook question="what happens on POST /orders" calls="3-4">search_code(exact_tokens: "orders") → get_chunk(OrdersController create action or class) → get_chunk_summary(Order model — macros reveal callbacks/validations) → answer; ONE callback/concern/job hop only if the question demands it.</playbook>
|
|
19
|
+
|
|
20
|
+
</environment_prompt>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="framework" name="react" requires="graph-indexer-core, javascript-typescript" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>React (JSX/TSX components, hooks). Loads after the javascript-typescript layer.</scope>
|
|
4
|
+
|
|
5
|
+
<critical_fact>JSX tags are NOT call expressions: `<MyComponent />` is a JSXElement, so get_call_graph("MyComponent") NEVER lists render sites and an empty call graph NEVER means a component is unused. Render sites come from `Used by:` (import topology — reliable in JS/TS) or ONE exact_tokens search on the component name.</critical_fact>
|
|
6
|
+
|
|
7
|
+
<rules>
|
|
8
|
+
<rule name="hooks-are-calls">Hook invocations ARE ordinary calls: get_call_graph("useAuth") reliably lists every component using that hook — the graph is trustworthy for hooks even though blind to JSX. A custom hook's contract is its return value — summary + Calls: line usually answers "what does it do" without the body.</rule>
|
|
9
|
+
<rule name="runtime-flow-invisible">State setter → re-render → effect firing is a runtime property no index sees. Answer ordering/timing from ONE get_chunk of the component, reasoning over hook semantics — never search for the render loop.</rule>
|
|
10
|
+
<rule name="wrappers">memo(...), forwardRef(...), HOCs export the WRAPPER. Resolution landing on a one-line wrapped export → the implementation is in the same file: get_file_skeleton(that file), not a new repo-wide search.</rule>
|
|
11
|
+
<rule name="context">Provider and consumers link through the Context OBJECT, not calls: ONE exact_tokens search on the context name ("ThemeContext") returns creation, Provider JSX, and consumers together.</rule>
|
|
12
|
+
<rule name="render-props">Logic injected via children/render props lives at the CALL SITE. If a component's body looks "empty", check ONE consumer to see what it injects.</rule>
|
|
13
|
+
<rule name="query-style">Component names are PascalCase and unique — exact_tokens with the component name is the highest-precision query here. For visual/behavioural questions ("the dropdown that closes on outside click"), use a behavioural sentence — handler names vary too much.</rule>
|
|
14
|
+
</rules>
|
|
15
|
+
|
|
16
|
+
<playbook question="explain component X and where it renders" calls="2-3">resolve_symbol("X") → get_chunk(id) — a component's body IS its behaviour (hooks + JSX), so the full chunk replaces two summary calls → answer citing Used by: as the render sites; ≤1 consumer chunk as a render example. Do NOT resolve every child component in its JSX.</playbook>
|
|
17
|
+
|
|
18
|
+
<playbook question="explain component X and its full ecosystem / what it's built from" calls="2-3">The child components X renders are IMPORTS, not calls — get_call_graph AND get_subgraph are BLIND to them (both walk the call graph, returning X's hooks/util calls, never its JSX children). The composition tree is the Deps: line on the resolve_symbol/get_chunk card (depth-1); render sites are Used by:. (1) resolve_symbol("X") → read Deps: for the direct child components. (2) For the FULL ecosystem / "what it's built from", the depth-2 grandchild is REQUIRED, not optional: resolve_symbol the PRINCIPAL child to read ITS Deps: — e.g. Modal's Deps: lists Fade; resolving Fade surfaces TransitionWrapper, which is NOT on Modal's card. A depth-1-only answer (Modal's children, stop) is INCOMPLETE for this question. Rule-of-one: hop into only the principal child; list the rest of X's children straight from its Deps:. NEVER get_subgraph to enumerate composition — it returns animation/hook plumbing, not the component tree.</playbook>
|
|
19
|
+
|
|
20
|
+
</environment_prompt>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="framework" name="spring-boot" requires="graph-indexer-core, java" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Spring / Spring Boot (annotation-driven config, container beans, AOP). Loads after the java (or kotlin) layer.</scope>
|
|
4
|
+
|
|
5
|
+
<critical_fact>ANNOTATIONS ARE BEHAVIOUR: @Transactional, @Cacheable, @Async, @Retryable, security annotations, and custom aspects wrap methods invisibly — bodies never show the transaction/cache/retry logic. Read the annotations in the summary BEFORE describing a method; never claim "no caching/transaction handling" from bodies alone.</critical_fact>
|
|
6
|
+
|
|
7
|
+
<rules>
|
|
8
|
+
<rule name="entry-points">Controller methods are dispatcher-invoked: empty call graphs on @RestController/@Controller methods mean ENTRY POINT. Full route = class-level prefix + method-level path. find_routes(method, path) resolves @GetMapping/@RequestMapping endpoints to the handler chunk_id with both parts joined — but ONLY for **Java** controllers; route extraction has no Kotlin branch, so on a **Kotlin** Spring app find_routes returns nothing and you must locate the handler with an `exact_tokens` search on the path fragment or annotation. For Java, use find_routes first and fall back to the exact_tokens path-fragment search only when it misses. Scheduled methods, listeners, queue consumers, lifecycle callbacks: the invoking annotation says WHO calls them — never hunt for callers.</rule>
|
|
9
|
+
<rule name="derived-queries">Repository interfaces generate query impls FROM METHOD NAMES: `findByEmailAndStatusOrderByCreatedAt` has NO body and NO chunk — the name IS the spec. Decode it; check for a @Query annotation in the summary when the name can't explain the result. Never search for the implementation.</rule>
|
|
10
|
+
<rule name="graph-works-below-wiring">Between project classes calls register normally: get_call_graph("calculateInvoice") reliably finds service-layer call sites. Trust the graph below the container wiring.</rule>
|
|
11
|
+
<rule name="interface-to-impl">Injection targets are interfaces; the container picks the impl. ONE exact_tokens search on the interface name surfaces the implementing class AND any @Bean factory — the binding is in one of those two.</rule>
|
|
12
|
+
<rule name="deep-inheritance">If a resolved class looks too thin, the behaviour lives in an abstract base — resolve ONE parent, guided by the extends list on the card.</rule>
|
|
13
|
+
<rule name="events-and-config">Event publishers and @EventListener handlers connect by the EVENT CLASS — ONE exact_tokens search on the event class finds both ends. @Value/configuration-properties bind to yml/properties — fallback condition 3 once the consuming class is located.</rule>
|
|
14
|
+
<rule name="query-style">Annotation names are high-precision tokens (exact_tokens: "@Scheduled"). Cross-cutting behaviour ("where do we audit changes") lives in an aspect/listener you can't name — search behaviourally.</rule>
|
|
15
|
+
</rules>
|
|
16
|
+
|
|
17
|
+
<playbook question="what happens on POST /orders" calls="3-4">find_routes("POST", "/orders") → get_chunk_summary(handler chunk_id, expand_calls: true) — annotations + called services in one shot → get_chunk_summary(the ONE service method doing the work) → answer; ONE impl/parent/aspect hop only if the question demands it.</playbook>
|
|
18
|
+
|
|
19
|
+
</environment_prompt>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="bash" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Bash/shell (.sh .bash). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact priority="critical">ONLY FUNCTIONS ARE CHUNKED. Top-level command sequences (script glue) have NO chunk — a script that runs purely at top level with no functions is INVISIBLE to search_code. Use get_file_skeleton(path) to read its structure; never conclude "nothing here" from an empty search.</fact>
|
|
7
|
+
<fact>`source x` / `. x` ARE tracked, so Deps:/Used by: reflect sourced libraries (relative paths resolve). A function you can't find in the current file is often DEFINED in a sourced lib — follow Deps:.</fact>
|
|
8
|
+
<fact>Every command is a potential call edge. Builtins and ubiquitous coreutils (echo, cd, grep, sed, awk, find…) are filtered; project functions and notable external tools (docker, git, npm, kubectl…) are kept as callees.</fact>
|
|
9
|
+
<fact>find_references returns caller signal only (no type annotations, no inheritance in shell). Call it only to find who calls a specific function; for non-call usage search, use exact_tokens instead.</fact>
|
|
10
|
+
</index_facts>
|
|
11
|
+
|
|
12
|
+
<rules>
|
|
13
|
+
<rule name="external-vs-internal">get_call_graph mixes calls to YOUR functions with invocations of external programs. A callee that doesn't resolve to an indexed function is an external command (a tool, not your code) — expected, never "dead code".</rule>
|
|
14
|
+
<rule name="names-are-global">No objects/namespaces and all calls are unqualified (empty receiver). Within a script + its sourced libs, function names are globally unique, so get_call_graph("deploy_app") is RELIABLE for your own functions — the OO-language precision worry doesn't apply.</rule>
|
|
15
|
+
<rule name="dynamic-invocation">`eval "$cmd"`, indirect expansion (`${!var}`), calling a function held in a variable (`"$handler" "$@"`), and `trap '…' EXIT` record NO usable edge. Find these by searching the function NAME as a string — it appears in the dispatch expression.</rule>
|
|
16
|
+
<rule name="subshells-and-pipes">Functions inside `$(...)`, pipes, and `&` jobs still record command calls, but variable side effects don't escape the subshell — answer state/ordering questions from the function's own body, not the graph.</rule>
|
|
17
|
+
<rule name="query-style">Function names are snake_case/kebab-case and split well; pin exact names with exact_tokens. To find an entrypoint, search the usage/help text or option-flag strings (`--force`, `usage:`) — far more unique than "main".</rule>
|
|
18
|
+
</rules>
|
|
19
|
+
|
|
20
|
+
<playbook question="explain what script X does" calls="1-3">get_file_skeleton(path) for the top-level flow → resolve_symbol("the_function") → get_chunk_summary(id, expand_calls: true). Follow at most ONE Deps: hop into a sourced lib for a function defined there.</playbook>
|
|
21
|
+
|
|
22
|
+
</environment_prompt>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="c" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is C (.c sources, .h headers). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: function definitions, named struct/union/enum specifiers, typedefs (incl. function-pointer typedefs), function-like macros (#define F(x) …). Bare prototypes (`int f(void);`) and object macros (`#define MAX 100`) are NOT chunked — resolve a prototype-only symbol from its .c definition.</fact>
|
|
7
|
+
<fact>Only quoted local includes (`#include "net/socket.h"`) are tracked; angle-bracket system includes are dropped. So Deps:/Used by: cover INTRA-PROJECT headers (reliable) but say nothing about libc/third-party.</fact>
|
|
8
|
+
<fact priority="critical">THE PREPROCESSOR IS NOT EXPANDED. Macro bodies are textual — a call inside a macro invocation is NOT an edge, and a symbol produced only by token-pasting (`##`) has no chunk. If a function that "must exist" is unfindable, a macro is generating it — read the function-like macro chunk, don't hunt for an expanded body.</fact>
|
|
9
|
+
</index_facts>
|
|
10
|
+
|
|
11
|
+
<rules>
|
|
12
|
+
<rule name="no-namespaces">No namespaces/classes: every name is global, so libraries collide (init, create, free_* recur). resolve_symbol returns many — disambiguate by card path or a subsystem hint ("socket buffer init").</rule>
|
|
13
|
+
<rule name="static-is-file-local">`static` functions are private to ONE translation unit, so the same static name legitimately exists in many .c files — the path is the disambiguator, they are not duplicates.</rule>
|
|
14
|
+
<rule name="function-pointer-dispatch">Polymorphism is a struct of function pointers (hand-rolled vtable): `ops->read(fd)` records callee `read` with receiver `ops`, but the REAL target is whatever was assigned to that field. get_call_graph through a pointer is ambiguous/empty — find the assignment with ONE search_code(exact_tokens: "the_concrete_fn") and read the initializer that wires it.</rule>
|
|
15
|
+
<rule name="header-vs-source">Declarations in .h, definitions in .c. Prefer the function_definition chunk (has the body); the struct/typedef chunk in the header is the type's shape. Empty call graph on a struct type is normal — enumerate consumers from Used by: + ONE exact_tokens search on the type name.</rule>
|
|
16
|
+
<rule name="query-style">snake_case splits well — bare behavioural words work; pin Struct/Enum/typedef names and ALL_CAPS macros with exact_tokens. For error flow, search the errno constant or the literal error message — far more unique than "error".</rule>
|
|
17
|
+
</rules>
|
|
18
|
+
|
|
19
|
+
<playbook question="explain function or subsystem X" calls="1-3">resolve_symbol("X") (disambiguate by path) → get_chunk_summary(id, expand_calls: true) → answer. Callback-driven flow: ONE exact_tokens search on the concrete function name to find where the pointer is installed — never read whole subsystem files to chase dispatch.</playbook>
|
|
20
|
+
|
|
21
|
+
</environment_prompt>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="csharp" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is C# (.cs). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: classes, interfaces, enums, methods, constructors, and PROPERTIES — a bodied property is its own chunk; resolve the property name directly, never a get_X accessor. Attributes are part of the chunk and often ARE the behaviour.</fact>
|
|
7
|
+
<fact>Topology RELIABLE — `using` directives tracked.</fact>
|
|
8
|
+
<fact>`partial` classes split one type across files: resolve_symbol("OrderService") may return several chunks of the SAME type — treat as one class; read the relevant part, list the rest.</fact>
|
|
9
|
+
<fact>Auto-properties, record positional members, compiler-generated members (Equals, Deconstruct) have no bodies anywhere — the type declaration IS the answer.</fact>
|
|
10
|
+
<fact>find_references on a type is FIELD-PRECISE: tracks usage as parameter types, field types, property types, return types, and base-list entries (~54% of chunks carry at least one type_ref) — the most complete type-usage channel in the suite. Prefer it over a name search when the question is "what code depends on this type".</fact>
|
|
11
|
+
</index_facts>
|
|
12
|
+
|
|
13
|
+
<rules>
|
|
14
|
+
<rule name="interface-dispatch">Call sites bind by NAME, usually against an interface: get_call_graph("Process") mixes every Process. Find implementations with ONE search_code(query: "implements the order service", exact_tokens: "IOrderService") — the `I` prefix makes interface names high-precision tokens.</rule>
|
|
15
|
+
<rule name="events-no-edges">`+=` wiring and delegate/Func invocations connect nothing in the graph — ONE exact_tokens search on the EVENT or delegate field finds subscription and raise sites together.</rule>
|
|
16
|
+
<rule name="linq-and-method-groups">LINQ chains record calls to Where/Select, not the lambdas inside; method groups (`list.Select(Map)`) create no edge to Map — find value-references with exact_tokens. Lambdas/local functions live inside their enclosing member's chunk.</rule>
|
|
17
|
+
<rule name="frameworks-and-generators">Reflection, DI containers, source generators invoke/create code with zero static edges: an empty call graph on a public member of an attributed class means FRAMEWORK-INVOKED or GENERATED, not dead.</rule>
|
|
18
|
+
<rule name="overloads-and-async">Overloads share a name — distinguish by parameter lists and say which you mean. async/await edges are normal, but fire-and-forget tasks decouple timing — answer ordering from ONE chunk's code.</rule>
|
|
19
|
+
<rule name="query-style">XML doc comments are indexed — behavioural queries match them. Exception flow: ONE exact_tokens search on the exception type finds throw sites and handlers together.</rule>
|
|
20
|
+
</rules>
|
|
21
|
+
|
|
22
|
+
<playbook question="explain service X" calls="2-3">resolve_symbol("X") (attributes + partials visible) → get_chunk_summary(id, expand_calls: true) → answer with Used by:; ≤1 caller/implementation hop.</playbook>
|
|
23
|
+
|
|
24
|
+
</environment_prompt>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="css-scss" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code includes stylesheets (.css .scss). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>RULE SETS chunk as their selector (selector + declaration block); the chunk's "symbol" is the selector. No import topology — Deps:/Used by: are empty.</fact>
|
|
7
|
+
<fact>SCSS @mixin and @function ARE indexed as NAMED chunks — resolve_symbol("button-variant") works; they are the reusable units worth searching by name. ($variables, @include sites, &-nesting are not separate chunks — find them by searching the token.)</fact>
|
|
8
|
+
<fact>get_call_graph DOES NOT APPLY (no call edges); for a mixin/function's call sites, search its name token. resolve_symbol is useful ONLY for @mixin/@function names, not plain selectors.</fact>
|
|
9
|
+
<fact>Very short rules (under ~2 lines) are filtered as trivial — a one-line utility class may be absent; widen the query or read the file if a tiny rule is the whole question.</fact>
|
|
10
|
+
<fact>get_file_skeleton is WEAK on stylesheets (mostly anonymous declaration nodes, no @keyframes names) — search_code by selector/mixin token instead.</fact>
|
|
11
|
+
<fact>In a MIXED repo, style chunks surface as noise in NL searches for other languages — add a path/directory hint to keep code queries on code.</fact>
|
|
12
|
+
</index_facts>
|
|
13
|
+
|
|
14
|
+
<rules>
|
|
15
|
+
<rule name="find-by-token">Styles for an element: ONE search of the class/id token, e.g. search_code(query: "card hover elevation styles", exact_tokens: ".card"). Variables/design tokens ($spacing, --color-primary): search the variable name — definition and usages return in one query.</rule>
|
|
16
|
+
<rule name="cascade-awareness">Several rule sets can target one element and the top hit may not win the cascade. For "why does this look wrong", read the 2-3 top-ranked rule sets FROM THE SAME RESULT — never a second search, never whole stylesheets.</rule>
|
|
17
|
+
<rule name="markup-side">WHERE a class is applied lives in components/markup, not stylesheets — that half belongs to the component language layer (search the class name string in code chunks).</rule>
|
|
18
|
+
</rules>
|
|
19
|
+
|
|
20
|
+
<playbook question="why does element X look wrong" calls="1-2">ONE search of the selector token (top_k: 10) → list every matching rule_set with file:lines, compare declarations → answer. Stylesheet chunks are tiny; one search almost always suffices.</playbook>
|
|
21
|
+
|
|
22
|
+
</environment_prompt>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="go" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Go (.go). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: top-level funcs, methods, type decls. A method's signature includes its RECEIVER — `func (s *Server) Start()` — so the card already says whose method it is; check the receiver before reasoning.</fact>
|
|
7
|
+
<fact>Topology RELIABLE — imports tracked.</fact>
|
|
8
|
+
<fact>Generated files (*.pb.go, mocks, stringer) are indexed like source and can dominate results — prefer detail: "signatures" and skip generated paths.</fact>
|
|
9
|
+
<fact>Struct construction (`&Engine{...}`, `Engine{}`, constructors returning `*T`) is NOT a call edge → get_call_graph("Engine") on a struct is EMPTY, never "unused". Enumerate consumers from Used by: + ONE search_code(exact_tokens: "Engine", detail: "signatures") for call-site locations; never read the whole defining file's skeleton.</fact>
|
|
10
|
+
</index_facts>
|
|
11
|
+
|
|
12
|
+
<rules>
|
|
13
|
+
<rule name="package-scoped-names">Every package has a New, a Config, a Client: resolve_symbol("New") returns many — disambiguate by package path on the cards, or query with a path hint ("storage client New connection pool").</rule>
|
|
14
|
+
<rule name="interface-dispatch">Interface satisfaction is implicit; call sites bind by method NAME: get_call_graph("Process") mixes every Process. Enumerate implementations: ONE search_code(query: "method receiver implementation", exact_tokens: "MethodName") and read the receivers off the signatures.</rule>
|
|
15
|
+
<rule name="embedded-promotion">A call to a method the outer type doesn't define lives in an EMBEDDED type — check the type-declaration chunk for embedded fields before distrusting the index.</rule>
|
|
16
|
+
<rule name="implicit-execution">init() and `_` blank imports run with no inbound edges — absence of callers is not dead code. `go fn()` and `defer fn()` ARE edges; channel flow is not — trace channels by searching the channel field name.</rule>
|
|
17
|
+
<rule name="first-class-functions">Functions passed as values (http.HandlerFunc(handle), middleware constructors) create no edge to the passed function — find sites with exact_tokens.</rule>
|
|
18
|
+
<rule name="query-style">Always include package/domain words ("auth middleware token refresh", never bare "Refresh"). To find where an error originates, search its message string literal — the most unique token in the flow.</rule>
|
|
19
|
+
</rules>
|
|
20
|
+
|
|
21
|
+
<playbook question="explain X / who implements interface I" calls="1-3">resolve_symbol("X") (check receiver) → get_chunk_summary(id, expand_calls: true) → answer. Implementors of I: ONE exact_tokens search on the method name — receivers in the signatures are the answer, no per-type reads.</playbook>
|
|
22
|
+
|
|
23
|
+
</environment_prompt>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="java" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Java (.java). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: classes, interfaces, enums, constructors, methods. Annotations are part of the chunk — summaries surface @Override, validation, and framework annotations that frequently carry the real behaviour.</fact>
|
|
7
|
+
<fact>Topology RELIABLE — imports tracked. One public class per file means path ≈ FQN: resolve_symbol("InvoiceService") is extremely reliable.</fact>
|
|
8
|
+
<fact>Chunking is CLASS-GRANULAR (god-class split only ≥200 lines) — methods are NOT their own chunks in small classes. get_call_graph on a method name returns callers at class level, not method level; name the method explicitly and confirm by class context on the cards.</fact>
|
|
9
|
+
<fact>Anonymous inner classes and lambdas have no named symbol — a Runnable defined inline lives in its enclosing method's chunk; find it by behavioural search.</fact>
|
|
10
|
+
</index_facts>
|
|
11
|
+
|
|
12
|
+
<rules>
|
|
13
|
+
<rule name="overloads-collapse">Overloads share one name: resolve_symbol("save") / get_call_graph("save") mix all signatures — distinguish by parameter lists on the cards and say WHICH overload you mean.</rule>
|
|
14
|
+
<rule name="polymorphic-dispatch">Call sites bind to the NAME as written, usually against an interface/superclass: verify the receiver's declared type before claiming a concrete impl is called. Enumerate overrides: ONE exact_tokens search on the method name — class context comes from each signature.</rule>
|
|
15
|
+
<rule name="inheritance-walk">If resolve_symbol finds a method only on a parent type, that IS the impl — resolve at most ONE parent up, never the whole hierarchy.</rule>
|
|
16
|
+
<rule name="frameworks-and-reflection">Class.forName, Method.invoke, DI containers, annotation processors invoke with ZERO static edges: an empty call graph on a public method of an annotated class means FRAMEWORK-INVOKED, not dead.</rule>
|
|
17
|
+
<rule name="functional-interfaces">Lambdas and method references (this::handle, User::getName) create no edge to the referenced method — find sites with exact_tokens.</rule>
|
|
18
|
+
<rule name="accessor-noise">Never read a POJO/bean body: detail: "signatures" or get_file_skeleton tells you everything a data class can. Exception flow: ONE exact_tokens search on the exception class finds throw sites and handlers together.</rule>
|
|
19
|
+
</rules>
|
|
20
|
+
|
|
21
|
+
<playbook question="explain service X / change a method safely" calls="2-4">resolve_symbol("X") (annotations visible) → get_chunk_summary(id, expand_calls: true) → answer with Used by:. Signature change: get_call_graph("method") → filter callers by class via paths → ONE caller chunk as template → edit.</playbook>
|
|
22
|
+
|
|
23
|
+
</environment_prompt>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="javascript-typescript" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is JavaScript/TypeScript (.js .jsx .mjs .cjs .ts .tsx). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: functions, classes, methods, exported consts. An arrow fn assigned to a const chunks under the VARIABLE name — resolve_symbol("handleSubmit") finds `const handleSubmit = () => {...}`.</fact>
|
|
7
|
+
<fact>Topology RELIABLE — ESM and require both tracked. Read Deps:/Used by: before any usage search.</fact>
|
|
8
|
+
<fact>Anonymous default exports (`export default () => {}`) have no stable name — locate via get_file_skeleton(path) or behavioural search, never by guessing.</fact>
|
|
9
|
+
<fact>Interfaces, type aliases, enums resolve like values but NEVER appear in get_call_graph (types aren't called) — usage from Used by: or ONE exact_tokens search.</fact>
|
|
10
|
+
<fact>`new ClassName()` DOES create a call edge → get_call_graph("Layer") returns construction sites: the cheap precise first move for a class's blast radius (~15 tok), no file reads. (A class used only as a type annotation shows none → Used by: + ONE search_code(exact_tokens: "Name", detail: "signatures").)</fact>
|
|
11
|
+
</index_facts>
|
|
12
|
+
|
|
13
|
+
<rules>
|
|
14
|
+
<rule name="barrel-files">Resolution landing on a re_export (index.ts barrel): internal origin → ONE hop to the origin; external dependency → stop, implementation is outside the repo.</rule>
|
|
15
|
+
<rule name="callbacks-no-edges">A function passed as a VALUE has no edge: `items.map(transform)` records a call to map, not transform. An empty call graph on a callback-style fn is NOT dead — find sites with ONE exact_tokens search.</rule>
|
|
16
|
+
<rule name="dynamic-imports">`await import(computedPath)` / `require(variable)` create no dependency edge. Empty Used by: on a module that should be popular → suspect dynamic loading before declaring it unused.</rule>
|
|
17
|
+
<rule name="name-overmatch">`this.method()` and property calls bind by NAME; common names (get, run, handle) overmatch across classes, and declaration merging returns several nodes for one name — pick by file path + node type on the cards, no extra reads.</rule>
|
|
18
|
+
<rule name="event-emitters">`emitter.on("event", fn)` pairs connect by STRING, not call edge — trace event flow by searching the event-name string.</rule>
|
|
19
|
+
<rule name="query-style">camelCase/PascalCase split well so partial-name keyword queries work; for async flows describe behaviour ("retries the fetch with exponential backoff"), never the keyword "async".</rule>
|
|
20
|
+
</rules>
|
|
21
|
+
|
|
22
|
+
<playbook question="explain service/module X" calls="2-3">resolve_symbol("X") → get_chunk_summary(id, expand_calls: true) → answer with the Used by: list; ≤1 consumer chunk as example.</playbook>
|
|
23
|
+
|
|
24
|
+
</environment_prompt>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="kotlin" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Kotlin (.kt .kts). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: functions, classes, OBJECT declarations, COMPANION OBJECTS, secondary constructors — resolve objects/companions by name like any class. Annotations are part of the chunk and often ARE the behaviour.</fact>
|
|
7
|
+
<fact>Topology RELIABLE — imports tracked.</fact>
|
|
8
|
+
<fact>Top-level functions/properties live directly in files: get_file_skeleton(path) is the fastest view of free functions. Lambdas and `let`/`apply`/`run`/`also` blocks have no symbol — that logic belongs to the enclosing chunk; find it behaviourally.</fact>
|
|
9
|
+
<fact>Data classes auto-generate copy/equals/hashCode/componentN with NO chunks — a "missing" method matching that list means the data-class declaration IS the answer.</fact>
|
|
10
|
+
<fact>Caller resolution is NAME-ONLY (no receiver class): get_call_graph mixes callers across every class sharing that method name — always verify receivers from card signatures before drawing conclusions. This is the same WEAK precision as Go/Rust/Ruby, not the receiver-aware precision of JS/TS/Python/C#.</fact>
|
|
11
|
+
</index_facts>
|
|
12
|
+
|
|
13
|
+
<rules>
|
|
14
|
+
<rule name="invoke-operator">`useCase(input)` dispatches to an `invoke` operator with NO edge — common in clean-architecture code. Empty call graph on invoke (or a use-case class) means nothing: find usage with ONE exact_tokens search on the class name.</rule>
|
|
15
|
+
<rule name="delegation">`by lazy`, `by viewModels()`, class delegation (`class A : B by impl`), property delegates route through getValue/setValue with no edges — resolve the DELEGATE expression's symbol when delegated behaviour is the question.</rule>
|
|
16
|
+
<rule name="lambdas-and-references">Trailing-lambda calls (`list.map { }`, `scope.launch { }`) record a call to the combinator only; `::handle` references create no edge — find sites with exact_tokens.</rule>
|
|
17
|
+
<rule name="name-overmatch">Like Java, call sites bind by NAME against interfaces/supertypes: get_call_graph("process") mixes every process — confirm receivers from card signatures. Extension functions resolve under the FUNCTION name (resolve_symbol("slugify")), not the receiver type. Custom property getters live in the PROPERTY's declaration, not a getX accessor.</rule>
|
|
18
|
+
<rule name="coroutines">suspend calls have normal edges, but launch/async decouple call site from execution — answer ordering questions from ONE chunk's code, not the graph.</rule>
|
|
19
|
+
<rule name="query-style">DSL/builder code has generic names — search behaviourally. Sealed hierarchies: ONE exact_tokens search on the SEALED PARENT name returns all variants and every `when` over them.</rule>
|
|
20
|
+
</rules>
|
|
21
|
+
|
|
22
|
+
<playbook question="explain class/use-case X" calls="2-3">resolve_symbol("X") (annotations + companion visible) → get_chunk_summary(id, expand_calls: true) → answer with Used by:; ≤1 delegate/interface hop.</playbook>
|
|
23
|
+
|
|
24
|
+
</environment_prompt>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="php" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is PHP (.php). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks are functions and WHOLE CLASSES — one class is ONE chunk with all its methods, UNTIL the class exceeds ~200 lines: a god-class is split so its methods become their own resolvable chunks. Class-sized questions on normal classes are cheap: one model/service class is one card, its full body one get_chunk.</fact>
|
|
7
|
+
<fact>get_file_skeleton(path) parses the live file and lists EVERY method + line ranges (~80 tok) — THE tool for a large class. One skeleton call replaces searching method names inside it.</fact>
|
|
8
|
+
<fact priority="critical">Topology WEAK BY DESIGN: only include/require tracked, namespace `use` imports are NOT. In autoloaded (PSR-4) code Deps:/Used by: are sparse/empty and mean NOTHING about usage. Map consumers by name search: chunks mentioning "ClassName" surface alongside its definition.</fact>
|
|
9
|
+
<fact>Closures and arrow functions have no symbol — callback logic belongs to the enclosing function/class chunk.</fact>
|
|
10
|
+
</index_facts>
|
|
11
|
+
|
|
12
|
+
<rules>
|
|
13
|
+
<rule name="batched-class-questions">"Explain classes A, B, C, D (and where used)" = ONE search_code(query: "A B C D", detail: "smart", top_k: 2×N). Definitions rank top (name boost), consumers follow. Escalate ONCE to detail: "full" + token_budget (e.g. 3000) when complete bodies of several small classes are needed. NEVER one resolve_symbol/search per class — the budget-killing failure.</rule>
|
|
14
|
+
<rule name="usage-mapping">Consumers of ONE class: search_code(query: "what it's used for", exact_tokens: "ClassName") — REPLACES the missing Used by:. get_call_graph works for function/method NAMES, not class references.</rule>
|
|
15
|
+
<rule name="one-method-of-a-class">In a normal (sub-200-line) class, method names aren't independently resolvable: get_file_skeleton(file) for the method map + line range, or get_chunk_summary(classChunkId) for the interface — only then decide if the full body is worth it. In a god-class (≥200 lines) the methods ARE their own chunks, so resolve_symbol / search_code on the method name hits directly.</rule>
|
|
16
|
+
<rule name="magic-methods">__call/__callStatic/__get/__set/__invoke route behaviour with NO edges. If a called method isn't in the class chunk, check its magic methods and `use TraitName;` lines — trait methods live in the TRAIT's chunk; resolve ONE trait.</rule>
|
|
17
|
+
<rule name="dynamic-dispatch">`$obj->$method()`, call_user_func, 'Class::method' strings create no edges — search the name as a string literal. Dispatch binds by name: get_call_graph("handle") mixes every handle; confirm receivers via class context.</rule>
|
|
18
|
+
<rule name="namespaces">Resolve SHORT class names; the file path mirrors the namespace under PSR-4 — disambiguate from paths on the cards, no extra calls.</rule>
|
|
19
|
+
</rules>
|
|
20
|
+
|
|
21
|
+
<playbook question="explain models Country, Community, Region, Location and where used" calls="1-2">ONE search_code(query: "Country Community Region Location", detail: "smart", top_k: 10) → the four model cards (relation methods in the smart body lines) plus the controllers/components mentioning them → answer structure AND usage. Optional 2nd call: detail: "full", token_budget: 3000 only if every method body must be quoted. Four resolve_symbol calls here = budget dead.</playbook>
|
|
22
|
+
|
|
23
|
+
</environment_prompt>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="python" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Python (.py). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: top-level defs, classes, methods. Decorator lines are INSIDE the chunk — routing/caching/permission behaviour is visible in summaries and searchable as body text.</fact>
|
|
7
|
+
<fact>Topology RELIABLE — absolute and relative imports tracked.</fact>
|
|
8
|
+
<fact>Calling a class — `UserService(...)` — records a call to the CLASS name: get_call_graph("UserService") finds instantiation sites; get_call_graph("__init__") is noise.</fact>
|
|
9
|
+
<fact>Module-level statements (constants, registrations, import-time side effects) live outside any function — if behaviour happens "at import time", get_file_skeleton(path) shows it; don't hunt for a function that doesn't exist.</fact>
|
|
10
|
+
</index_facts>
|
|
11
|
+
|
|
12
|
+
<rules>
|
|
13
|
+
<rule name="name-overmatch">Dispatch binds by NAME and Python is duck-typed: get_call_graph("save") mixes every save repo-wide, and resolve_symbol may return several — pick by file path + class context from the cards, no extra reads.</rule>
|
|
14
|
+
<rule name="dunder-magic">Implicit protocol calls have no edges: `obj()`↛__call__, `a+b`↛__add__, attr access↛__getattr__, `with`↛__enter__/__exit__. An empty call graph on a dunder means nothing.</rule>
|
|
15
|
+
<rule name="package-barrels">`__init__.py` re-export hubs produce re_export nodes: internal origin → ONE hop; external dependency → stop.</rule>
|
|
16
|
+
<rule name="decorators-wrap">Call sites point at the DECORATED name even when a decorator wraps it. If runtime behaviour is the question, read the decorator's chunk ONCE — never trace every wrapped function.</rule>
|
|
17
|
+
<rule name="string-references">getattr/importlib/task-queue registrations and monkey-patching reference code by STRING — no edges. Trace by searching the string literal; when observed behaviour contradicts the source, ONE search of the patched name as a literal.</rule>
|
|
18
|
+
<rule name="query-style">snake_case splits perfectly ("parse_request_body" matches "parse request body") and docstrings are indexed — query with docstring vocabulary. For duck-typed behaviour use a behavioural sentence, not the method name.</rule>
|
|
19
|
+
</rules>
|
|
20
|
+
|
|
21
|
+
<playbook question="explain function/class X" calls="2-3">resolve_symbol("X") (decorators visible) → get_chunk_summary(id, expand_calls: true) → answer with Used by: list; ≤1 consumer OR the ONE behaviour-defining decorator.</playbook>
|
|
22
|
+
|
|
23
|
+
</environment_prompt>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="ruby" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Ruby (.rb). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: methods, singleton methods (`def self.x`), classes, MODULES. Instance vs class methods of the same name are DIFFERENT chunks — check the signature for which you hold.</fact>
|
|
7
|
+
<fact priority="critical">Topology WEAK: only require/require_relative tracked, and most apps autoload — Deps:/Used by: are sparse/empty and mean NOTHING about usage. Map consumers by name search: bodies are indexed, so chunks mentioning "ClassName" surface in the same search as its definition.</fact>
|
|
8
|
+
<fact>Reopened classes produce MULTIPLE chunks for one name — reopening, not duplication; treat them together, read only the one matching your concern.</fact>
|
|
9
|
+
<fact>Blocks (`do...end`, `{ }`) have no symbol — logic passed to each/map/DSL methods belongs to the enclosing chunk; find it behaviourally.</fact>
|
|
10
|
+
<fact>find_references: callers + extends/includes channels only; type_refs (annotation-usage) channel is EMPTY — Ruby is dynamically typed, no annotation tracking. "Where is this class used as a type" must be answered by name search, not find_references.</fact>
|
|
11
|
+
</index_facts>
|
|
12
|
+
|
|
13
|
+
<rules>
|
|
14
|
+
<rule name="metaprogrammed-methods">define_method, method_missing, attr_accessor/attr_reader, delegate macros create methods with NO chunks. If resolve_symbol misses a method callers clearly use, ONE search of the SYMBOL LITERAL (exact_tokens: ":method_name") or the macro line — the macro call IS the definition.</rule>
|
|
15
|
+
<rule name="duck-typed-dispatch">Everything dispatches by NAME: get_call_graph("call")/("perform") overmatches massively — prefer rarer names as graph entry points and confirm receivers from context. send/public_send invoke by symbol with no edge — search the symbol literal.</rule>
|
|
16
|
+
<rule name="mixins">Methods arrive via include/extend/prepend — if a class responds to a method it doesn't define, its include lines (in the class chunk) name the module; resolve ONE module.</rule>
|
|
17
|
+
<rule name="implicit-hooks">included/inherited/method_added hooks and yield-passed blocks run with no inbound edges — not dead code; the behaviour of `process { }` splits between the method chunk and the ONE call site that matters.</rule>
|
|
18
|
+
<rule name="query-style">snake_case splits perfectly; pin ?/! suffixed names with exact_tokens. For DSL-heavy code search the DSL keyword or symbol literal ("validates", ":before_save") — the declaration site is the behaviour. Resolve namespaced constants by the LAST segment, disambiguate by path.</rule>
|
|
19
|
+
</rules>
|
|
20
|
+
|
|
21
|
+
<playbook question="explain classes A, B, C (and where used)" calls="1-2">ONE search_code(query: "A B C", detail: "smart", top_k: 2×N): definitions rank top, consumers (bodies mentioning the names) follow — this REPLACES the missing Used by: topology. Escalate ONE chunk to full body only if needed.</playbook>
|
|
22
|
+
|
|
23
|
+
</environment_prompt>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="rust" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Rust (.rs). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact>Chunks: top-level fns, impl-block methods, traits, structs, enums. Attribute lines (#[...]) are part of the chunk — derives and attribute macros are visible in summaries and often ARE the behaviour.</fact>
|
|
7
|
+
<fact>Topology RELIABLE — `use` declarations tracked.</fact>
|
|
8
|
+
<fact priority="critical">MACROS ARE NOT EXPANDED: code from #[derive(...)], attribute macros, and macro_rules! has NO chunks, and calls written inside macro invocations may be missing from the call graph. If an impl that "must exist" is unfindable (e.g. Serialize for a struct), the struct's derive attribute IS the answer — never hunt for generated bodies.</fact>
|
|
9
|
+
</index_facts>
|
|
10
|
+
|
|
11
|
+
<rules>
|
|
12
|
+
<rule name="hidden-calls">Rust inserts calls the source never spells: `?`→From::from, operators→Add::add etc., Deref coercion→deref, scope end→Drop::drop, `.await`→poll. None appear as edges — never call a trait method unused from an empty call graph.</rule>
|
|
13
|
+
<rule name="trait-dispatch">Calls through generics (T: Trait) or dyn Trait bind to the method NAME: get_call_graph("execute") mixes every execute. Disambiguate by the impl target in each signature. Enumerate implementors: ONE search_code(query: "impl TraitName for", exact_tokens: "TraitName").</rule>
|
|
14
|
+
<rule name="re-exports">`pub use` hubs (crate roots, preludes) produce re_export nodes: internal origin → ONE hop; external crate → stop.</rule>
|
|
15
|
+
<rule name="closures-and-generics">Logic inside closures passed to combinators has no edges — behavioural search. A generic fn is ONE chunk regardless of instantiations; per-type behaviour comes from its trait bounds — resolve the bound trait's method ONCE, per-type copies don't exist.</rule>
|
|
16
|
+
<rule name="query-style">snake_case splits well; pin PascalCase trait/type names with exact_tokens. For error flow, search the error variant name or the thiserror/anyhow message string — far more unique than "error". Trust card file paths over guessed `crate::` paths.</rule>
|
|
17
|
+
</rules>
|
|
18
|
+
|
|
19
|
+
<playbook question="explain type X and its trait impls" calls="1-2">ONE search_code(query: "X impl trait", top_k: 8) — the struct chunk and its impl chunks surface together (name boost); attributes on the struct card answer derive questions. Escalate ONE chunk to full body only if implementation detail is the question.</playbook>
|
|
20
|
+
|
|
21
|
+
</environment_prompt>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<environment_prompt layer="2" type="language" name="swift" requires="graph-indexer-core" version="1.0">
|
|
2
|
+
|
|
3
|
+
<scope>Indexed code is Swift (.swift). Deltas to core; hard limits unchanged.</scope>
|
|
4
|
+
|
|
5
|
+
<index_facts>
|
|
6
|
+
<fact priority="critical">struct, class, enum, extension, actor ALL appear with card type `class_declaration` — the card does NOT distinguish them, so READ THE KEYWORD in the signature before reasoning about value vs reference semantics. A god-type is split so its methods become their own chunks.</fact>
|
|
7
|
+
<fact priority="critical">A type's behaviour is SPREAD across its base declaration AND every `extension` — each is a separate chunk, all carry the SAME name, possibly in different files. resolve_symbol("Point") returns the struct AND every extension; protocol conformance is usually in an extension. Read them together, not just the first card.</fact>
|
|
8
|
+
<fact>Topology WEAK: `import Module` is recorded but Swift resolves by MODULE not file path — an empty Used by: is uninformative, never "unused".</fact>
|
|
9
|
+
</index_facts>
|
|
10
|
+
|
|
11
|
+
<rules>
|
|
12
|
+
<rule name="protocol-dispatch">Protocol calls bind by NAME across every conformer: get_call_graph("draw") mixes every draw(). Disambiguate by receiver type in each card. Enumerate conformers: ONE search_code(query: "conform protocol", exact_tokens: "ProtocolName") — extension conformances surface by the protocol name.</rule>
|
|
13
|
+
<rule name="attributes-are-behaviour">Property wrappers/attributes are part of the chunk and frequently ARE the behaviour: @Published, @State/@Binding, @MainActor, @objc, @escaping. A computed property's logic lives in the PROPERTY declaration, not a synthesized getX accessor.</rule>
|
|
14
|
+
<rule name="synthesized-has-no-chunk">Memberwise inits, synthesized Codable/Equatable/Hashable, enum case accessors have NO chunks — a "missing" member matching that list means the type declaration (or its Codable conformance) IS the answer.</rule>
|
|
15
|
+
<rule name="closures-and-builders">Trailing closures/combinators (`.map { }`, `Task { }`, `DispatchQueue.async { }`) record a call to the combinator only; SwiftUI `body` and result builders generate view structure with no edges. Closure logic belongs to the enclosing chunk — find it behaviourally. `super.m()`/`self.m()` record receiver hints.</rule>
|
|
16
|
+
<rule name="query-style">camelCase splits well; pin Type names and argument labels with exact_tokens. A method written `distance(to:)` is searched by its base name `distance`. For error flow, search the thrown error case name or its message string.</rule>
|
|
17
|
+
</rules>
|
|
18
|
+
|
|
19
|
+
<playbook question="explain type X and its conformances" calls="1-3">ONE search_code(query: "X", exact_tokens: "X") — the base declaration and its extension chunks surface together via the name boost; read keyword + attributes off the cards → get_chunk_summary(id, expand_calls: true) on the primary chunk. ≤1 protocol hop.</playbook>
|
|
20
|
+
|
|
21
|
+
</environment_prompt>
|