Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
799be10
release 0.1.5: every package and plugin manifest at 0.1.5 (the parser…
swapnilpaliwal-sd Sep 28, 2026
a722752
python: a pytest fixture reaches exactly the tests that receive it (#…
swapnilpaliwal-sd Sep 28, 2026
66ebc2f
java: Spring Boot registrations make beans, and impact names who regi…
swapnilpaliwal-sd Sep 28, 2026
c95a99b
Merge pull request #1631 from AxiomCodeAI/fix/1537-pytest-fixture-vis…
swapnilpaliwal-sd Sep 28, 2026
9d626cc
Merge pull request #1629 from AxiomCodeAI/fix/1392-boot-bean-registra…
swapnilpaliwal-sd Sep 28, 2026
503275b
java: a published Spring application event reaches the listeners its …
swapnilpaliwal-sd Sep 28, 2026
ac69770
java: point the event-dispatch comment at knobs.dl section (20) after…
swapnilpaliwal-sd Sep 28, 2026
63bfa13
impact: bump IMPACT_VERSION to 31, so a cache written before event di…
swapnilpaliwal-sd Sep 28, 2026
f150473
python: a route reaches its view through decorators, include() and as…
swapnilpaliwal-sd Sep 28, 2026
af178c4
csharp: a mediator Send or Publish reaches the handler for the reques…
swapnilpaliwal-sd Sep 28, 2026
289a317
plugin: compile the query rules once per machine, never while a query…
swapnilpaliwal-sd Sep 28, 2026
6502b9b
changed / test-impact: read a branch from its merge-base, name what t…
swapnilpaliwal-sd Sep 28, 2026
b88d732
graph: draw the existing graph, and every rebuild keeps the languages…
swapnilpaliwal-sd Sep 28, 2026
16831fd
context: equal-scoring entry points are ordered by what the question …
swapnilpaliwal-sd Sep 28, 2026
c06a7ea
Merge pull request #1630 from AxiomCodeAI/fix/1391-spring-events-rfix
swapnilpaliwal-sd Sep 28, 2026
70951cf
Merge pull request #1633 from AxiomCodeAI/fix/1510-python-url-dispatc…
swapnilpaliwal-sd Sep 28, 2026
4ad10f5
Merge pull request #1635 from AxiomCodeAI/fix/1383-mediatr-inprocess
swapnilpaliwal-sd Sep 28, 2026
df85476
Merge pull request #1634 from AxiomCodeAI/fix/1606-query-rule-cache
swapnilpaliwal-sd Sep 28, 2026
a3f00f9
Merge pull request #1639 from AxiomCodeAI/fix/1470-changed-range-merg…
swapnilpaliwal-sd Sep 28, 2026
9ee9d59
Merge pull request #1642 from AxiomCodeAI/fix/graph-verb-reuses-index…
swapnilpaliwal-sd Sep 28, 2026
b271a22
Merge pull request #1643 from AxiomCodeAI/fix/1392-mapper-context-seed
swapnilpaliwal-sd Sep 28, 2026
c34fec2
typescript: a decorator container's constructor slots are injection p…
swapnilpaliwal-sd Sep 28, 2026
c098e1c
typescript: a string literal that is a key of a `keyof` constraint se…
swapnilpaliwal-sd Sep 28, 2026
6dd53f0
impact / path: a file:line written ./path, absolute under the reposit…
swapnilpaliwal-sd Sep 28, 2026
a7dac96
python: 1-based field lines, and a per-language schema guide for the …
swapnilpaliwal-sd Sep 28, 2026
829a3ca
javascript: a call through a memoize/once wrapper returns what that s…
swapnilpaliwal-sd Sep 28, 2026
ec894e4
build: a stopped query or index no longer loses the main graph (#1555)
swapnilpaliwal-sd Sep 28, 2026
366468d
javascript: stop manufacturing wide value sets through string and typ…
swapnilpaliwal-sd Sep 28, 2026
b9653a9
javascript: a write through a typedef keeps what is later called or i…
swapnilpaliwal-sd Sep 28, 2026
125e229
ts: a call through an annotation the parser cannot read stays unresol…
swapnilpaliwal-sd Sep 28, 2026
820749a
hooks: one source table for every hook, the directive once per sessio…
swapnilpaliwal-sd Sep 28, 2026
d1196ab
Merge pull request #1651 from AxiomCodeAI/fix/schema-guide-per-langua…
swapnilpaliwal-sd Sep 28, 2026
4a7a6fb
Merge pull request #1647 from AxiomCodeAI/fix/main-graph-published-0.1.5
swapnilpaliwal-sd Sep 28, 2026
a1a8f23
Merge pull request #1652 from AxiomCodeAI/loop/ja-is1600
swapnilpaliwal-sd Sep 28, 2026
9ab3c01
Merge pull request #1636 from AxiomCodeAI/loop/ty-is536
swapnilpaliwal-sd Sep 28, 2026
317c7df
Merge pull request #1637 from AxiomCodeAI/loop/ja-is732
swapnilpaliwal-sd Sep 28, 2026
decee85
java: a var in an enhanced for, a try-with-resources resource and a l…
swapnilpaliwal-sd Sep 28, 2026
d8be101
Merge pull request #1648 from AxiomCodeAI/loop/ja-is695
swapnilpaliwal-sd Sep 28, 2026
717eba6
Merge pull request #1656 from AxiomCodeAI/loop/ty-is334
swapnilpaliwal-sd Sep 28, 2026
08f82a8
Merge pull request #1650 from AxiomCodeAI/fix/hooks-csharp-edit-and-a…
swapnilpaliwal-sd Sep 28, 2026
349cf9b
Merge pull request #1632 from AxiomCodeAI/fix/1401-var-shapes-finish
swapnilpaliwal-sd Sep 28, 2026
54caa56
Merge pull request #1662 from AxiomCodeAI/loop/ty-is1109
swapnilpaliwal-sd Sep 28, 2026
a2276bd
ci: key the compiled engine cache on the CPU's feature flags, and dro…
swapnilpaliwal-sd Sep 28, 2026
b071da4
typescript: a function held in an array or table is run by the call t…
swapnilpaliwal-sd Sep 28, 2026
d84d63e
Carry 0.1.4 forward into 0.1.5: 2 commit(s) made on 0.1.4 while it wa…
swapnilpaliwal-sd Sep 28, 2026
d104149
Merge pull request #1665 from AxiomCodeAI/port/0.1.4-into-0.1.5-5b6c815d
swapnilpaliwal-sd Sep 28, 2026
c0c531a
Merge pull request #1664 from AxiomCodeAI/fix/ts-engine-cache-cpu-flags
swapnilpaliwal-sd Sep 28, 2026
6f06bc3
Merge pull request #1657 from AxiomCodeAI/loop/ty-is967
swapnilpaliwal-sd Sep 28, 2026
2ac30b0
impact, path and hooks: each dependent once, prose is not a binding, …
swapnilpaliwal-sd Sep 28, 2026
490539f
path: an outside-world entry keeps its wording in the library-call no…
swapnilpaliwal-sd Sep 28, 2026
f8a1fdc
tests: the one-row-per-dependent fixture uses neutral names
swapnilpaliwal-sd Sep 28, 2026
34197bb
tests: the event listener's answer uses the per-tier event wording, a…
swapnilpaliwal-sd Sep 28, 2026
dc866d1
Merge pull request #1641 from AxiomCodeAI/fix/1389-one-row-per-dependent
swapnilpaliwal-sd Sep 28, 2026
b642598
javascript: on one line an anonymous function nests only where its qu…
swapnilpaliwal-sd Sep 28, 2026
3b0b8cc
parser: 0.1.2, for the parser changes on 0.1.4
swapnilpaliwal-sd Sep 28, 2026
8f42010
Merge pull request #1671 from AxiomCodeAI/release/0.1.5-parser-0.1.2
swapnilpaliwal-sd Sep 28, 2026
c889a90
Merge pull request #1674 from AxiomCodeAI/loop/ja-is1598
swapnilpaliwal-sd Sep 28, 2026
45c9fdf
Merge dev (the 0.1.4 release) into 0.1.5
swapnilpaliwal-sd Sep 28, 2026
eacc2d8
Merge pull request #1687 from AxiomCodeAI/port/dev-into-0.1.5
swapnilpaliwal-sd Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,15 @@ jobs:
# Two things decide the binary that ENGINE_ID does not cover, so they are in the
# key too: the driver that compiles it (run-souffle.sh holds the compiler flags),
# and the runner's CPU, because the driver compiles with -march=native and a
# binary built on one CPU model can die with an illegal instruction on another.
# binary built on one CPU can die with an illegal instruction on another.
# The CPU part hashes the FEATURE FLAGS, not only the model name: hosted runners
# that report the same model name do not all expose the same instruction set, so
# a model-name key restored a binary that died with SIGILL on every case.
- name: this language's engine id
id: eid
run: |
echo "id=$(bash graph/pipeline/run-souffle.sh --language ${{ matrix.lang }} --print-engine-id)" >> "$GITHUB_OUTPUT"
echo "cpu=$(grep -m1 'model name' /proc/cpuinfo | sha256sum | cut -c1-12)" >> "$GITHUB_OUTPUT"
echo "cpu=$(grep -E '^(model name|flags)[[:space:]]*:' /proc/cpuinfo | sort -u | sha256sum | cut -c1-12)" >> "$GITHUB_OUTPUT"

- name: cache the compiled Soufflé engine
if: ${{ !inputs.fresh }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ about one change had to read 95 of 43,793 methods, and every true direct caller
| `axiomcode test-impact` | which tests have to run for the current edit, with the chain that reaches each |
| `axiomcode changed` | which declarations an edit changed, and how (signature, type, body, added, removed). `--impact` adds what that reaches |
| `axiomcode context "<task>"` | where a task's words land in the code, when you have a problem statement and not yet a name |
| `axiomcode graph` | the whole graph as one self-contained HTML page, at `.axiomcode/graph/graph.html` |
| `axiomcode graph` | the whole graph as one self-contained HTML page, at `.axiomcode/graph/graph.html`, drawn from the existing graph (rebuilt first only when stale, with the flags it was indexed with) |
| `axiomcode index` | build or rebuild the graph explicitly; `--lang`, `--src` and `--library` narrow it |
| `axiomcode mcp` | serve the graph to an agent as MCP tools over stdio |

Expand Down
2 changes: 1 addition & 1 deletion gemini-extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axiomcode",
"version": "0.1.4",
"version": "0.1.5",
"description": "Ask your repository how its code connects: who calls this, what breaks if I change it, which tests an edit reaches, how A reaches B. Answers come from a resolved call graph and are verified against it; nothing is guessed.",
"contextFileName": "plugins/axiomcode/AGENTS.md",
"mcpServers": {
Expand Down
19 changes: 14 additions & 5 deletions graph/bundle/SCHEMA.md

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions graph/bundle/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,20 @@ export async function buildCore(inp: BuildInputs): Promise<CoreTables> {
}
}
}
if (A.ir.localSites) {
const L = A.ir.localSites;
const src = await clientSource(inp.clientIrDir, L.file);
if (src) {
const h = src.header;
const ci = h.col(L.id), cl = h.col(L.startLine), cel = h.col(L.endLine);
for await (const r of rowsOf(src)) {
const row = sites.get(r[ci] ?? '');
if (!row) continue;
fill(row, 4, fileOf(L.fileVia, h, r));
fill(row, 5, int(r[cl])); fill(row, 7, int(r[cel]));
}
}
}
// a site keyed on a type (Python METACLASS_CREATION) is positioned at the class declaration
for (const row of sites.values()) {
if (row[5] !== null) continue;
Expand Down
14 changes: 14 additions & 0 deletions graph/bundle/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ export interface CallSitesIR {
file: string; expressionId: string; calleeName: string; startLine: string; startColumn: string; endLine?: string;
fileVia: { column: string; through: 'modules' };
}
/**
* Java try-with-resources: the implicit close() edge is keyed on the resource LOCAL, which has no
* expression row, so the site is positioned at the local's declaration instead.
*/
export interface LocalSitesIR {
file: string; id: string; startLine: string; endLine: string;
fileVia: { column: string; through: 'modules' | 'types' };
}
/**
* Python decorators — a site id may be the decorator's own hash (a bare decorator with no
* expression row) or the decorator's EXPRESSION hash; the row links both, so it is matched
Expand Down Expand Up @@ -150,6 +158,7 @@ export interface LanguageAdapter {
expressions: ExpressionsIR;
callSites?: CallSitesIR;
decorators?: DecoratorsIR;
localSites?: LocalSitesIR;
/** absent where the front end writes no skipped-files report */
skipped?: SkippedIR;
};
Expand Down Expand Up @@ -207,6 +216,11 @@ const JAVA: LanguageAdapter = {
// the parser puts the invoked name / created class name in literalValue for these kinds
calleeName: { column: 'literalValue', kinds: ['METHOD_INVOCATION', 'OBJECT_CREATION', 'METHOD_REFERENCE', 'ANONYMOUS_CLASS_CREATION'] },
},
// a resource_close site is the try-with-resources resource local, positioned at its declaration
localSites: {
file: 'all-local-variables.csv', id: 'localVariableRegistryUniqueHash', startLine: 'startLine', endLine: 'endLine',
fileVia: { column: 'typeRegistryLinkHash', through: 'types' },
},
// The Java report carries no construct and no position: the three reasons it emits
// (EMPTY_CONTENT, FILE_TOO_LARGE, READ_ERROR) are properties of the whole file.
skipped: { file: 'skipped-java-files.csv', filePath: 'filePath', reason: 'reason' },
Expand Down
19 changes: 14 additions & 5 deletions graph/bundle/schema.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions graph/csharp/engine/call-edge-generation/call_chain.dl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
// ambiguous_dynamic a call through `dynamic`. Unresolvable BY DESIGN: the DLR
// decides at runtime. Separated from ambiguous_unknown so a
// known-undecidable site is never counted as an engine failure.
// event_dispatch NOT the site's own target: a framework runs this method for the
// site in process (a mediator's Send reaching the handler for the
// request type). Added beside the site's row, by
// framework-behavior/dispatch.dl.
// ============================================================================

// ── THE SITE UNIVERSE ───────────────────────────────────────────────────────
Expand Down
26 changes: 17 additions & 9 deletions graph/csharp/engine/framework-behavior/destinations.dl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ call_recv_written_name(e, n) :-
ref_denotes("client", r, "LOCAL_VARIABLE", v), var_is_implicit("client", v),
var_value_initializer("client", v, init), expr_new_type_ref("client", init, tr),
type_ref_name("client", tr, n).
// …and a property read off another value, `services.Mediator.Send(..)`: a minimal-API
// endpoint takes its services as one parameter object, and the receiver is that
// object's property, whose declared type name is what the project wrote.
call_recv_written_name(e, n) :-
call_receiver_expr("client", e, r), property_access("client", r, p, _),
property_type_name("client", p, n, _), n != "".
// …and a `var` from the service locator, which holds its type argument
call_recv_written_name(e, n) :-
call_receiver_expr("client", e, r),
Expand Down Expand Up @@ -706,24 +712,26 @@ msg_bus_arg(e, a) :- msg_bus_send_site(e, _, _), http_arg(e, 0, a), !msg_first_i
msg_bus_arg(e, a) :- msg_bus_send_site(e, _, _), msg_first_is_address(e), http_arg(e, 1, a).
msg_first_is_address(e) :- msg_bus_send_site(e, _, _), http_arg(e, 0, a0), http_arg(e, 1, _),
expr_literal("client", a0, k, _), k != "NULL".
// the message's type NAME, however it is written
msg_arg_type_name(a, n) :- msg_bus_arg(_, a), expr_new_type_ref("client", a, tr), type_ref_name("client", tr, n0), last_segment(n0, n).
msg_arg_type_name(a, n) :- msg_bus_arg(_, a), expr_kind("client", a, "OBJECT_CREATION"),
// the message's type NAME, however it is written. Read for a bus send here and for an
// in-process mediator send (dispatch.dl), which carries its request the same way.
msg_typed_arg(a) :- msg_bus_arg(_, a).
msg_arg_type_name(a, n) :- msg_typed_arg(a), expr_new_type_ref("client", a, tr), type_ref_name("client", tr, n0), last_segment(n0, n).
msg_arg_type_name(a, n) :- msg_typed_arg(a), expr_kind("client", a, "OBJECT_CREATION"),
call_callee_name("client", a, n0), last_segment(n0, n).
msg_arg_type_name(a, n) :- msg_bus_arg(_, a), expr_type("client", a, gk), type_group("client", t, gk),
msg_arg_type_name(a, n) :- msg_typed_arg(a), expr_type("client", a, gk), type_group("client", t, gk),
type_decl("client", n, _, _, _, t).
msg_arg_type_name(a, n) :- msg_bus_arg(_, a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
msg_arg_type_name(a, n) :- msg_typed_arg(a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
var_type_name("client", v, n0, _), n0 != "", last_segment(n0, n).
msg_arg_type_name(a, n) :- msg_bus_arg(_, a), ref_denotes("client", a, "PARAMETER", p),
msg_arg_type_name(a, n) :- msg_typed_arg(a), ref_denotes("client", a, "PARAMETER", p),
param_type_name("client", p, n0, _), n0 != "", last_segment(n0, n).
// A local declared as a BASE is usually assigned a concrete message on each branch,
// Notice evt; if (ok) evt = new Accepted(..); else evt = new Rejected(..);
// and those constructions, in the same method, are what it can hold.
msg_arg_type_name(a, n) :- msg_bus_arg(_, a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
msg_arg_type_name(a, n) :- msg_typed_arg(a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
msg_local_assigned(v, c), msg_creation_name(c, n).
msg_arg_type_name(a, n) :- msg_bus_arg(_, a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
msg_arg_type_name(a, n) :- msg_typed_arg(a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
var_value_initializer("client", v, c), msg_creation_name(c, n).
msg_local_assigned(v, c) :- msg_bus_arg(_, a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
msg_local_assigned(v, c) :- msg_typed_arg(a), ref_denotes("client", a, "LOCAL_VARIABLE", v),
expr_kind("client", asg, "ASSIGNMENT"), expr_child("client", asg, "ASSIGNMENT_TARGET", _, t),
ref_denotes("client", t, "LOCAL_VARIABLE", v), expr_child("client", asg, "ASSIGNMENT_VALUE", _, c).
msg_creation_name(c, n) :- expr_kind("client", c, "OBJECT_CREATION"), expr_new_type_ref("client", c, tr),
Expand Down
Loading
Loading