Repository navigation
Apps/integration 0.1.9 - #1890
Merged
Merged
Conversation
…ding A module-scope const used as `X.m`, `f(X)`, in a template or under `typeof X` had no data edge to its declaration, so impact matched it by name, including same-named consts in sibling packages whose files import their own. - TypeScript and JavaScript engines export field_access rows for an identifier the binder ties to a module variable, directly or through an import binding (across `export *` barrels); `typeof X` type queries bind through module scope, with a same-named parameter or local shadowing it. - The bundle positions a field-access site that is a type reference. - impact: a const the engine bound on a route line is still a registration. - Goldens re-blessed: module consts read by name now carry known_edge reads. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…s only through that instance - JavaScript engine: a new expression of a class whose instance code calls a value carries its allocation beside the instance; instance-state.dl names the edges that hold only for instances given the callee (constructor option, subscription, injected dependency) and the allocations each caller's receiver may be - a callee that also reaches the class another way (named inside it, returned to it, written onto it from outside, a class hierarchy, an entry with an unknown receiver) is not gated - impact walks a gated edge through the class's own code and leaves it only for a caller whose receiver may be an allocation given the callee, or is unknown; the SQL port does the same Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…eads; --in narrows text files A context question with a common word (debug, optional, string) listed package-lock.json and package.json lines as "text files that name these declarations" and made one of them the next step, even when --in named a directory holding neither file. - ax_nonsource: lockfiles of every package manager (npm, pnpm, yarn, NuGet, Gradle, Poetry, uv, Composer, Cargo, Go) are out of scope; a manifest's metadata and dependency lists (package.json, pyproject.toml, PackageReference) and package.json keys are skipped by line. Script commands and tool configuration values are still searched. - context: the caller's --in narrows text bindings as it narrows declarations; a mapper XML whose namespace names the declaring type stays (bound by the declaration, not the word). - ax_pages: a --source answer with no flow and no text row now ends with a next step. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…anifest; --in text dirs stay in scope The previous commit on this branch added the case but not the code it checks, and its npm lockfile fixture was gitignored, so CI ran the checks against the old scripts. - ax_nonsource: one manifest filter decided by where a word sits (entry, table, block, element), not by line: package.json, bower.json, deno.json, composer.json by JSON entry (a one-line manifest keeps its scripts); pnpm-workspace.yaml and conda environment.yml by block; pyproject.toml and Pipfile by table; requirements files whole; pom.xml, MSBuild, packages.config and .nuspec by package element. More lockfiles recognised. - context: the word-matched rows of a text-only --in use the same filter; a directory the main graph holds is no longer text to another language's graph; with several graphs, a text-only --in is answered once and never by a package outside it. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…aration
`export const TOPICS = { orderEvents: '…' } as const` names topics, routes,
event types and DI tokens, and `TOPICS.orderEvents` is how every user reads
one. The keys were declared nowhere: `impact TOPICS.orderEvents` answered
"nothing named", and the readers of one key could not be told from another's.
- parser: an unannotated module-level `const` whose value is an object
literal (through `as const`, `satisfies`, parentheses, `Object.freeze`)
emits each data key as an OBJECT_LITERAL_PROPERTY field owned by the
variable; a nested literal's keys are owned by the key that holds it.
Function-valued keys stay methods.
- field_access.dl: `X.a` resolves to that field when X is the variable, an
import of it, a namespace import's export of it, or a key of an outer
table, and only when the typed lookup found nothing (`satisfies T` keeps
T's member). A read inside a method's decorator is that method's.
- index: a field whose owner is no type is displayed after the module
(`ROUTES.admin.users`).
- impact.dl: for a module-owned key, a line declaring another field of the
same name is not a read (two route tables in one file with the same key).
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
`TOKENS.Relay` (a key of a module-level const table) also matched class Relay by dropping the table's name, and impact answered 'more than one kind'. A field whose display is the spelling now wins over a type found only by dropping the leading segment, as a method already did. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
`constructor(@Inject(TOKENS.Store) store)` binds the constructor to the token, but the read was credited to the module that evaluates the decorator, so `impact TOKENS.Store` named the file instead of the class. A parameter decorator's owner is the parameter; its method is the reader, as for a method's own decorator. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
`constructor(topic = TOPICS.payments)` evaluates the default on every call that omits it, but the read was placed in the module initializer, so the constructor was missing from the key's readers. A parameter's default expression is now its method's, unless a function written as the default already owns the read. Reads in a decorator no longer also add a module row. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…the compiler names it
The fields scorer labelled a key of a module-level `const X = { a: … }` as
`X#a` (its owner is the variable, which is no type). The compiler side names
the nearest enclosing named declaration and the module otherwise, so every
correct read scored as one wrong plus one missing. Label it by its module.
- 78-cross-process-destinations: fields 0/1 -> 1/1 correct, 0 wrong
- 80-object-literal-member-receivers: fields 0/9 -> 3/9 correct, 0 wrong
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…eclaration landed The index declared data keys of TypeScript const literals too, so after merging, an annotated const's keys were declared a second time beside the type's member. The parser now owns TypeScript's keys; the index keeps them for JavaScript. - index: no TypeScript consts predicate (the parser declares those keys) - parser: a const annotated with a type that names no member (Record<K, V>, through Readonly/Partial/Required, or index signatures only) declares its literal's keys, as an unannotated one does - impact.dl: keep both the key-declaration-line and other-table-line rules - suite: fixture 86's const-table reads now resolve (fields recall 0.50 -> 0.92) Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
… field An edit, insertion or comment on a later line of a const or field whose initializer spans several lines was reported as a body change of the module (or 'inside' the type), so test-impact seeded from the whole module. It is now the field's 'initializer changed'. A callable written inside the initializer keeps its own body; a Python module-level name is measured by its statement, not its first-to-last binding span. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
… lambda keeps its body Since data keys of const objects are declarations, an edit to a key's value was read as a typed field: 'type 3, → 4,', and on a one-line const 'LIMIT.max renamed → LIMIT'. It is now the key's 'initializer changed'. A lambda on a later line of a multi-line initializer is its own body again, as a method written there already was. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…ect method
`impact Repo.get` listed every `x.get(...)` whose receiver the engine could not
type, and among them the calls on what an unstaged package returned or
constructed (`request(app).get('/x')`, `new grpc.Metadata().get(k)`). Those
filled the first page ahead of the real leads, and seeded the by-name closure,
so tests that only issue HTTP requests counted as tests of the method.
- JavaScript and TypeScript engines: `library_receiver(site, specifier)`, an
unresolved member call whose receiver is rooted in a bare-specifier import no
staged IR declares (a binding, a member of one, a call or `new` on one, an
await of one, a never-reassigned const holding one). A call handed a project
instance is left out, since a wrapper or mock helper may return it.
- impact: such a site is the unresolved kind "library": its own by-name row,
sorted last and grouped as [library receiver] in --grep, no closure seed, no
param row; path's by-name group and the SQL fast path agree.
- Goldens: case 28 gains the shapes and controls; other JS cases gain their
library_receiver diagnostics (edges unchanged).
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…t-member-declaration TypeScript: each key of a module-level const object literal is a declaration
…t-matches-in-lockfiles context/impact: lockfiles and manifest package lists are never text leads; --in narrows text files
…onst-initializer-change-attri changed: an edit inside a multi-line const initializer is that const's
…ts after 61 Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
The 78/80 goldens both sides regenerated are blessed again from the merged engine (the result differs from the integration tip by exactly this PR's rows), and the two 86 tests gain the reads this PR resolves (module consts read through their bindings); no resolved row is lost. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…nst-read-through-member-acces engine: resolve reads of module-level consts through their import binding
…s-from-library-receivers impact: a call on a package's value is not a by-name caller of a project method
…cess and the state relations Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…e-registration-treated-global impact: a callback given to one instance reaches callers only through that instance
…s complete A caller reached through an interface was explained with the precision figure for target sets the engine could not narrow, so the only correct answer read as a guess and agents re-read the source to check it. Dispatch rows now get their own legend, and a `complete:` line is printed when no row is by-name, text or a capped set and nothing inside the impacted set is unresolved. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…iomCodeAI/axiom-code-graph into fix/impact-trustworthy-output
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…rgument does `def getter(val, field_obj=field_obj): return field_obj.deserialize(val)` -- the closure idiom that pins a loop variable -- is called with one argument, so field_obj only ever holds its default, and no call site passes it: the parameter was untyped and the call on it unresolved. The default is a value the def statement writes once (the parser links it, param_default_expr); value-flow.dl now lets it reach the parameter exactly as a call-site argument does -- an instance types it, a class object makes it that class, a function makes it callable as that function -- alongside whatever callers pass. A parameter defaulted to a name from an enclosing scope appears in fifteen of sixteen public repositories (sentinels and constants included, which type nothing callable). Mutation oracle, sixteen repositories: one tuning repository +13 failing test files selected (16 added files do not fail), none lost, every other repository unchanged. Case parameter-default-types-it fails 2 of 3 on the base; control: an argument passed at a call site still reaches the parameter. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…o it only where the module sits under the dropped segments findModule dropped leading segments of an import it could not match exactly and then matched what was left exactly or by suffix. `from clikit.testing import CliRunner` dropped `clikit` and found the project's own `testing` package (or `app.testing` by suffix); `from fw.db import models` found the project's `models.py`. A dependency's module whose last segments collide with one of the project's resolved INTO the project, the import bound nothing, and every call through it was unresolved instead of a named boundary. The drop exists for an import more qualified than the module (`import myproject.framework` naming a `framework` in a `myproject/` directory with no __init__.py). The analyzer now records the directories above each module's top package, and a dropped prefix must be what the module actually sits under. Python engine goldens: 33-url-view-forms, 37-model-signals and 38-app-wiring move sites from ambiguous_unknown to boundary_lib (`external:path`, `external:models.CharField`, `external:call_command`); edges, framework edges and the torture harness are otherwise unchanged. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
… hands back to the objects the client gives it The engine reads a dependency's signatures, never its bodies, so a hop the LIBRARY makes back into client code was invisible: a test client's get() runs the open() a client subclass overrides and then calls the application it was built around; a CLI runner's invoke(cli) runs cli.main(), which runs the command's callback; a decorator wraps a def into a library object that later calls it; ExitStack.enter_context(cm) runs cm.__enter__. On a 16-repository Python oracle a library frame was the first broken hop behind most test-impact misses of the web-framework subject, and every one of them stopped at the library. graph/python/libsum/libsum.py derives the hand-backs from the library's SOURCE (the project's own environment, its stdlib through pyvenv.cfg, or AXIOMCODE_PY_SITE): a flow-insensitive pass per function records which parameter-rooted value meets which call or protocol syntax, composed to a fixpoint across the library's own calls (self-calls, typed parameters and fields, constructors, closures, decorator factories). It writes, for the library classes and functions the client can name, five tables beside the client IR: the hand-backs (callee, root, position, path, member, via, declared type), constructor stores, re-exports, what a decorator turns a def into, and class ancestors. Cached by the installed distributions and the client's imports, so a refresh that adds no import reuses them. Staged through a new client-extra.map (facts beside the IR that are not parser schema); absent = empty = no change. framework-behavior/library-callbacks.dl joins them to the client: a member a client type inherits from its library base, a super() past the client classes, a library function or class the client imported, a member of a library object the client built (followed through locals, helpers' returns and fixtures) or one a library decorator made of a def. Each hand-back resolves to the client member of the object that arrives -- the receiver, an argument, a field the library constructor filled, a field the client set -- and only when none answers, to the client subclasses of the type the library declares there. It ADDS lib_callback_edge (caller, target, callee, member, via, how) and lib_callback_site, and leaves call_chain_edge alone. No library or framework is named in a rule. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
… hop `library callback` impact reads the Python engine's lib_callback_edge as fw_edge "library callback": a test that drives a library now reaches the client member the library hands back to, with the rung `library callback` (ranked with `registered`: a library's behaviour joined by a member name, never a resolved call). lib_callback_site marks a call site the engine knows enters a library callable as a library receiver, so it is never a by-name seed: a test client's `client.put()` no longer reaches the project's own `put` by name. tests/cases/python/library-calls-back: a fake site-packages with a test client, a CLI runner and command decorator, a template environment whose loader arrives through **options and a function calling a member on its argument; each positive check fails on the base engine. Controls: the same member name on a class never handed to a library, an object handed to a library function that never calls that member, a same-named member on a class that is not a subclass of the declared library type. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…ependent impact names
path adds lib_callback_edge to the hops no call site expresses, worded `library_callback via <callee> -> <member>`
and verified against the engine's table, so a test reaches the application its test client calls; impact lists
the client method that calls the library as a [framework] dependent of the member handed back
("a library it calls hands this back (<callee> calls <member>)"), which is what path's note points at.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
# Conflicts: # graph/python/souffle/decls_all.dl # parser/src/parsers/python/extractors/python-resolution-linker.ts # parser/src/workflows/python/python-project-analyzer.ts # plugins/axiomcode/skills/axiomcode/scripts/axiomcode-impact
… the f-string golden A Python call site with more candidate targets than the cap was refused outright, so every test reached only through it was dropped from a selection. For test selection a missed test costs more than an extra one, so Python solves uncapped unless --dispatch-cap is given; every other language keeps 20. The protocol-fan check tests the cap mechanism itself and now pins it explicitly. The parser's Python golden records an f-string's leading text (literalValue), as the getattr dispatch change made it do; only that column moved, on 14 rows. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
`a == b`, `a | b`, `x in c`, `-a`, `if x:`, `not x`, `x or y` compile to no call, so the
client __eq__, __or__, __contains__, __bool__ or __len__ they run had no caller: impact listed
nothing that compares, composes or truth-tests the object, and a test doing exactly that was
not selected. Two new protocol edges on the existing channel, each its own kind:
OPERATOR_PROTOCOL the left operand's slot and the right operand's reflected one (a
comparison's mirror, `a < b` -> b.__gt__), `!=` falling back to __eq__,
`in` running the right operand's __contains__ (or __iter__), and the
unary -, +, ~. A chained comparison matches no catalogue row and emits
nothing.
TRUTH_PROTOCOL if / while / assert conditions, a conditional or comprehension
condition, `not x`, and the operands of `and`/`or` -- the right one only
when the whole expression is tested (`return a or b` hands b back
untested). __bool__, or __len__ when the class has none.
Operators and dunders are catalogued in builtins.dl (the data model's tables).
Mutation oracle, sixteen repositories: +5 failing test files selected (one tuning, four
held-out), 9 extra, none lost; empty answers 96 -> 92; impact's one-hop callers src recall
0.707 -> 0.714 (tuning 0.726 -> 0.736); a failing test's path to the change found 0.528 ->
0.541. Edges +0.8%, index time flat. Case operator-runs-the-dunder fails 6 of 8 on the base;
controls: a class with its own __bool__ is never tested through __len__, and the untested
right operand of `or` reaches nothing.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…xport or a generic alias is that class
A client class whose base is a library class was recognised only when the base was a bare
name or a subscript. Three spellings of the same base left it a plain unresolved class, so the
library's own methods never called back the overrides it defines:
* a DOTTED base, `class Command(clikit.core.Command)` / `class Store(abc.Mapping)`: the
base list's DOTTED_NAME slot is read like NAME (138 such classes across the sixteen
repositories, every one of them);
* a name a library re-exports with `from M import *` (`collections.abc.MutableMapping` is
`_collections_abc.MutableMapping`): libsum now loads every module first and expands star
imports (M's __all__ when it declares one, else its public names) before analysing any
body, so the alias table has the row;
* a module-level generic alias built around a class, `Mapping = _alias(collections.abc.
Mapping, 2)`: followed only when the first argument resolves to a library CLASS, so a
`partial(f, x)` wrapper around a function is not taken for f.
Mutation oracle, sixteen repositories: tests recall 0.786 -> 0.851 (tuning 0.884 flat, +1
file; held-out 0.713 -> 0.826, +536 files on a CLI subject whose commands subclass the
library's by dotted name), precision 0.431 -> 0.417, empty answers 92 -> 83; a failing
test's path to the change found 0.541 -> 0.559. Two tuning files lost to a by-name match
the new library site suppressed are restored by the next commit. Case library-star-reexport
fails 4 of 5 on the base; control: a library base whose method hands nothing back never
reaches the client's __getitem__.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…s a hand-back from it is summarised A call the engine knows enters a summarised library callable (ext_lib_callback_site) was made a library receiver outright, which drops its by-name callers. Where the summary does say what the library hands back from that call (a lib_callback_edge from the same caller through the same callable), that is right: the hand-back is the answer and a project method merely named like the call is not. Where it says nothing -- the library reaches the project through a method's return, a registry, anything the summary cannot follow -- knowing the call enters a library is no evidence that nothing in the project runs behind it, and the name match it had before the library was read is kept. Found when naming more library bases (previous commit) turned a test client's `super().__init__(...)` into such a site and two failing test files lost the only route the graph had to them. Mutation oracle, sixteen repositories: both restored, +17 extra files, 0 lost; empty answers 83 -> 80. IMPACT_VERSION 69 and path EXPORT_VERSION 5, since the staged facts change. Case library-site-without-summary: the base fails the name-match check; control: a call whose hand-back is summarised still reaches no project method merely named like it. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
… from the body
A scope-less context call ranks directories by where the HEADLINE's words land, and refuses
with a menu when they land nowhere. A report titled in prose ("Release 8.4.2", "Disable when
developing?", "Make unimported utilities private") lands nowhere by its headline while its body
names the code outright (`@retry(wait=wait_fixed(1))`, `LazyFile`, `make_short_help`), and the
refusal answered NOTHING. The whole report's words now rank the directories when the headline's
have no evidence; the pick stays an offered scope (it neither filters nor weights), and a report
whose words land nowhere at all still refuses.
Issue-to-fix oracle (92 tasks, sixteen repositories): empty answers 6 -> 0 (three repositories),
recall@5 0.846 -> 0.891, recall@10 0.881 -> 0.933, MRR 0.703 -> 0.744; tuning 0.799 -> 0.837
recall@5, held-out 0.894 -> 0.946. No task lost a gold file. Case context-body-names-the-code:
the base refuses ("--in <path> is required"); control: a headline that lands still chooses the
place by itself.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
0.1.9: impact and test-selection fixes across Python, JavaScript, TypeScript, Java and C#
Python test selection: library callback summaries, seven recall fixes, no dispatch cap
…ated, and what staging buys Closes #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…es), made once per dependency The entry the skill led with was a dependency's source directory, which index re-parses; the reusable form is the CSV IR `axiomcode parser <source> <ir dir> --library` writes. Lead with that, keep the source directory as the accepted fallback. Refs #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…comma, unresolved vs external Every claim in the --library section was exercised: two IR entries stage two roots; a space after a comma is refused as "not a directory"; a relative entry resolves against the repository; a source directory is parsed under .axiomcode/out/.intermediate/lib/; AXIOMCODE_LIBRARY works the same; a bare index keeps the library graph. A `~` after a comma is refused (a leading one is the shell's), and without libraries a dependency call is unresolved or an external boundary, not always unknown. Refs #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…orts; a source entry is compiled once Libraries are opt-in: the graph is built without them unless --library is given. `--library auto` finds the packages the project's source imports, in its virtual environment or under node_modules, compiles each once into ~/.cache/axiomcode/libir with `bin/axiomcode parser --library`, and stages the compiled tables. A named source directory goes through the same cache, so a rebuild the refresher starts after an edit no longer parses it again (a large dependency was re-parsed on every edit). A library IR entry passes through unchanged. The skill says when to do this: for better coverage, compile the dependencies and enable them. Refs #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…ases for `--library auto` in JS and TS TypeScript names a library method module#Member (`index#Greeting.shout`); the library endpoint lookup matched only a `.`-separated tail, so `path welcome Greeting.shout` said nothing of that name was declared although the call resolved into the library. Cases cover discovery from node_modules and a call typed through the package in both languages; each fails without the build change. Refs #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…ough their sources jars
auto reads the dependencies pom.xml (a ${property} version resolved) and build.gradle declare, finds
each one's -sources.jar in the Maven repository (.mvn/maven.config's maven.repo.local, else ~/.m2) or
Gradle's module cache, unpacks it once and compiles it like any source library. A dependency with no
sources jar is named, with the command that fetches it.
Refs #1887.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…by decompiling them NuGet packages ship assemblies, not source. auto reads the PackageReferences each .csproj declares (a version Directory.Packages.props sets centrally too), finds the package in the folder NUGET_PACKAGES, nuget.config's globalPackagesFolder or ~/.nuget/packages names, decompiles its assembly once with ilspycmd and compiles the C# like any source library. A package never restored is named, and a missing ilspycmd is reported with the command that installs it; CI installs it for the C# leg. With this, auto covers all five languages, and the skill says so. Closes #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
… no sources jar A dependency with only a class jar was reported and left out. It is now decompiled with Vineflower (found in the Maven repository, or AXIOMCODE_JAVA_DECOMPILER) once into the cache and compiled like a source library; with no decompiler the dependency is named with the commands that fetch sources or the decompiler. CI fetches Vineflower for the Java leg. Refs #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…y changes; old compiled libraries are pruned Only source files were compared, so a dependency added, removed or upgraded without a source edit (`pip install -U`, `npm install`, `dotnet restore`, a manifest or lockfile edit) left the graph on the libraries it was built with. The file table of a graph built with --library now also records the manifests and lockfiles and what is installed (a virtual environment's dist-info names, npm's install record, .NET's restore output); a difference marks the graph stale and the usual background rebuild runs, which re-discovers `auto` and compiles only what changed. A graph built without libraries is unaffected and never gains them by itself. A compiled library no build has used for 30 days is removed from the cache, with what was unpacked or decompiled for it; one in use is never removed. The skill states both, and how to turn libraries off again. Refs #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…brary graph stale Fetching a missing Java dependency (`mvn dependency:resolve`, a Gradle build) writes only to ~/.m2 or Gradle's cache, which no file in the project records, so the graph stayed without that library until the next source or pom edit. The dependency fingerprint now includes which declared dependencies are present in the Maven repository or Gradle's cache; one appearing marks the graph stale, and the refresh stages it. Refs #1887. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Python recall (operators, library bases, context) and --library auto for every language
swapnilpaliwal-sd
requested review from
JaredHLZhang,
Whua689 and
suyashpaliwal26
as code owners
October 10, 2026 05:42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Improvements
--library autostages the project's dependencies in all five languages:node_modulespip install,npm install,dotnet restore, a Maven fetch) rebuilds the graphparams=and@parametrizevaluesrepr/len/strreach the operand's dunder; property setters and deleters are callspkg.mod.Base, through a star re-export or an alias, are recognisedgetattr(self, f"visit_{…}")dispatch,python -m pkgspawns,with … as, dict.items()loops, Optional/union locals and default-valued parameters are typedconftest.pyfiles above it.d.ts; callbacks through test-hot functions andwrapper(impl)results are followedJSON.parse,Promise.resolve) are no longer by-name callersit(/test.each(, vitest/jest set-up files,Object.assignfunction objects and overload implementations (TypeScript: multi-line test registrars, runner set-up files, Object.assign function objects, overload implementations (stacked on #1882) #1888)equals/hashCode/toStringand library overrides are reached through constructorsusingresources, implicitbase(), static members through the type name, generic receivers, and extension methods on types outside the projectBugs
.pyibeside it resolved to the stub, so tests reached nothing in the packageif __name__ == "__main__":was taken as run on importx.testing) resolved into the projectpathrefused every.csfile as an endpointpathdid not find a library method by its member namePerformance
linkProjectlookups are maps