Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/e2e/windows-cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ no-name-yet
one-row-per-dependent
path-crosses-framework-and-byname
path-through-interface
quoted-literal-text
receiver-from-an-importlib-module
registration-key
route-table-reaches-view
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ established relationships that could lead to false positives.

AxiomCode Graph is two parts. The **engine** (`@axiomcode/code-graph` on npm) parses a repository and builds its
graph; it also provides the `axiomcode` command and an MCP server. The **plugin** (`plugins/axiomcode/`) is the
agent-facing frontend: a skill, four MCP tools, and hooks. Install the engine first.
agent-facing frontend: a skill, five MCP tools, and hooks. Install the engine first.

Requirements: **Node ≥ 22.13** and **Python 3** (`python3`, or `python` / `py` on Windows). On Windows, also
[Git for Windows](https://git-scm.com/download/win): the CLI runs under its bash. The engine ships as a prebuilt
Expand All @@ -139,7 +139,7 @@ your platform. No Soufflé and no compiler are needed, with one exception:
> `sudo apt install build-essential python3`. The full `node:*` Docker images already include them.

Before every release, the exact packages that ship are installed without Soufflé and run end to end (every CLI verb,
five languages) on macOS arm64 and x64, Linux x64 and arm64, and Windows x64. Check an install with
six language engines, including HTML/CSS) on macOS arm64 and x64, Linux x64 and arm64, and Windows x64. Check an install with
`axiomcode --version`.

### Installation
Expand Down Expand Up @@ -262,7 +262,7 @@ looked up again in the graph before you see it; the `verified:` line is that che

### Support for agents

Every agent below gets the four MCP tools and the skill; the hooks, which keep the graph current and report what an
Every agent below gets the five MCP tools and the skill; the hooks, which keep the graph current and report what an
edit breaks, run where the last column says so. No hook annotates the agent's own reads and searches.

| Agent | Hooks |
Expand Down Expand Up @@ -353,8 +353,10 @@ hooks and the MCP server's timer never rebuild a graph another axiomcode built (

## Graph output

The graph is one SQLite database, `.axiomcode/out/graph.sqlite`, with the **same schema for
every language** and its documentation inside it (`schema_guide`, `schema_queries`, `schema_vocab`). The main
Each language has its own SQLite database: the main language at `.axiomcode/out/graph.sqlite`, and other
languages at `.axiomcode/lang/<lang>/out/graph.sqlite`. The CLI queries all of them; calls are not followed
across languages. Each database has the **same schema for every language** and its documentation inside it
(`schema_guide`, `schema_queries`, `schema_vocab`). The main
tables are `call_edges` (one row per call site and possible target), `methods`, `types`, `call_sites`,
`field_access`, `type_use`, and `unresolved_sites`, the calls the engine declares it could not resolve.

Expand Down
4 changes: 4 additions & 0 deletions bin/axiomcode
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ set -eu
if [ -n "${AXIOMCODE_ARGV+x}" ]; then
set --; while IFS= read -r -d $'\x1f' _a; do set -- "$@" "$_a"; done < <(printf '%s' "$AXIOMCODE_ARGV"); unset AXIOMCODE_ARGV _a
fi
# and Git Bash's runtime rewrites an argument that looks like a POSIX path as it starts a native program, so
# `impact '"/orders/{code}"'` reached Python as "C:/Program Files/Git/orders/{code}". A quoted query is never a path:
# an argument that starts with a quote is left as written, and every other one (a repository path) is converted as before.
case "${OSTYPE:-}" in msys*|cygwin*) export MSYS2_ARG_CONV_EXCL="\"${MSYS2_ARG_CONV_EXCL:+;$MSYS2_ARG_CONV_EXCL}";; esac
# RESOLVE $0 THROUGH SYMLINKS BEFORE THE WALK. npm installs a `bin` entry as a link in
# node_modules/.bin, so under `npx axiomcode` or a global install $0 is that link and
# dirname "$0" is .bin/, a directory this package does not live under. The walk below then
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.2.1",
"version": "0.2.2",
"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
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@axiomcode/code-graph",
"version": "0.2.1",
"version": "0.2.2",
"description": "AxiomCode Graph: a resolved call graph of your codebase grounded in formal methods, so you and your coding agents can see who calls what, what a change breaks, and which tests it reaches.",
"repository": {
"type": "git",
Expand Down Expand Up @@ -31,11 +31,11 @@
],
"license": "FSL-1.1-Apache-2.0",
"optionalDependencies": {
"@axiomcode/engine-darwin-arm64": "0.2.1",
"@axiomcode/engine-darwin-x64": "0.2.1",
"@axiomcode/engine-linux-x64": "0.2.1",
"@axiomcode/engine-linux-arm64": "0.2.1",
"@axiomcode/engine-win32-x64": "0.2.1"
"@axiomcode/engine-darwin-arm64": "0.2.2",
"@axiomcode/engine-darwin-x64": "0.2.2",
"@axiomcode/engine-linux-x64": "0.2.2",
"@axiomcode/engine-linux-arm64": "0.2.2",
"@axiomcode/engine-win32-x64": "0.2.2"
},
"bin": {
"axiomcode": "bin/axiomcode.js"
Expand Down
2 changes: 1 addition & 1 deletion plugins/axiomcode/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "axiomcode",
"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.",
"version": "0.2.1",
"version": "0.2.2",
"author": {
"name": "AxiomCode"
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/axiomcode/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axiomcode",
"version": "0.2.1",
"version": "0.2.2",
"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.",
"author": { "name": "AxiomCode", "url": "https://github.com/AxiomCodeAI/axiomcodegraph" },
"homepage": "https://github.com/AxiomCodeAI/axiomcodegraph",
Expand Down
2 changes: 1 addition & 1 deletion plugins/axiomcode/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axiomcode",
"version": "0.2.1",
"version": "0.2.2",
"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. Java, TypeScript, Python, JavaScript.",
"author": { "name": "AxiomCode" },
"homepage": "https://github.com/AxiomCodeAI/axiomcodegraph",
Expand Down
4 changes: 4 additions & 0 deletions plugins/axiomcode/skills/axiomcode/scripts/axiomcode
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
if [ -n "${AXIOMCODE_ARGV+x}" ]; then
set --; while IFS= read -r -d $'\x1f' _a; do set -- "$@" "$_a"; done < <(printf '%s' "$AXIOMCODE_ARGV"); unset AXIOMCODE_ARGV _a
fi
# and Git Bash's runtime rewrites an argument that looks like a POSIX path as it starts a native program, so
# `impact '"/orders/{code}"'` reached Python as "C:/Program Files/Git/orders/{code}". A quoted query is never a path:
# an argument that starts with a quote is left as written, and every other one (a repository path) is converted as before.
case "${OSTYPE:-}" in msys*|cygwin*) export MSYS2_ARG_CONV_EXCL="\"${MSYS2_ARG_CONV_EXCL:+;$MSYS2_ARG_CONV_EXCL}";; esac
H="${0//\\//}"; case "$H" in */*) H="${H%/*}";; *) H=.;; esac; H="$(cd "${H:-/}" && pwd)" # no `dirname`: see bin/axiomcode

# PYTHON UNDER ANOTHER NAME (#1331). Every verb runs `python3`, which a python.org install on Windows does not
Expand Down
4 changes: 2 additions & 2 deletions tests/mcp_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
[os.path.join(ROOT, 'plugins', 'axiomcode', 'AGENTS.md')] + \
sorted(glob.glob(os.path.join(ROOT, 'plugins', 'axiomcode', 'rules', '*.mdc')))

VERB = r'(find|impact|path|tests)'
VERB = r'(context|impact|link|path|tests)'
# a tool named: a call `impact(`, the Claude Code name mcp__plugin_axiomcode_axiomcode__impact, MCP `impact`, or a command
# in backticks (`axiomcode impact x`); `path:line: …` is an answer's shape, not the tool
MENTION = re.compile(r'`(?:axiomcode )?' + VERB + r'(?:[ \t][^`\n]*)?`|\bmcp__plugin_axiomcode_axiomcode__' + VERB + r'\b'
Expand Down Expand Up @@ -130,7 +130,7 @@ def controls(tools):
got = len(mismatches(documented(text), fake, 'control'))
if got != want:
bad.append(f"control {text!r}: {got} mismatch(es), want {want}")
if set(tools) != {'impact', 'path', 'tests'}:
if set(tools) != {'context', 'impact', 'link', 'path', 'tests'}:
bad.append(f"the server listed {sorted(tools)}; the MCP tools were not read")
return bad

Expand Down
Loading