Repository navigation
Apps/integration 0.2.0 - #1957
Merged
Merged
Conversation
graph/test/web/oracle/ derives the ground truth for every web node and in-web edge kind from parse5, postcss, css-select and acorn (pinned in its package.json; the axiom parser is never imported). run-tests.sh builds each case's graph, normalizes the engine tables onto the oracle's rows (contract in tools/normalize.py) and gates the multiset diff with known-missing support; it fails with "engine not built" until graph/web/engine exists. 51 hand-written cases across nodes, cascade, refs, pages, js and crosslang, two generated scale cases; every expectation was read row by row and agrees with the oracle (--oracle). Refs #1908
…eyframe selector lists Three corpus shapes the oracle-vs-IR comparison exposed: keyframes named only through -webkit-/-moz-/-o-animation, theme sheets annotating every value with a brace comment, and percentage lists in minified keyframes. Declaration values are compared without comments; usemap, codebase and profile join the URL attributes. Refs #1908
…cle skips matching when no kind needs it The suites live on web/torture while the engine is built on feat/web-layer: AXIOM_ROOT points the runner at that checkout. The oracle's matching stage now runs only for kinds that depend on it, so the 2,000-page scale case takes 2 s in the oracle. The 200-page scale case compares styles and cascade rows; var edges are left out (4.5M rows on the generated site). Refs #1908
Clearing the namespace of a universal node threw inside the selector rewrite, so every selector containing `*` became selector_unparsed: thousands of corpus selectors (`* html`, `> *`, `*::before`) had no match rows. Found by listing the selector_unparsed partition on the dev corpus; one invalid selector remains there, as it should. New case cascade/17 covers both. Refs #1908
…larations after a comment holding braces
The web walk skipped dist/, build/ and out/ by name (the source walks' list), so a
template's own compiled stylesheet, linked by every page, was never read. The web
walk now has its own skip list (EXCLUDED_DIRS less those three); javadoc/Dokka and
git-ignored directories are still skipped.
A comment holding a brace inside a declaration value (#ddd/*{borderColor}*/) turned
the rest of the block into bogus nested rules. Braces inside comments are blanked for
the grammar only; comment rows read their text from the source.
Refs #1909
…dies as JavaScript modules of their page The HTML/CSS tables are also written to <ir>/web/ whenever a page or stylesheet was read, so a repository of pages and stylesheets alone has IR for the web engine. The JavaScript front end reads each page's inline classic/module <script> bodies and on* attribute values as modules of their own: file = the page, qualified name <page>#script-<n> / <page>#on-<n> (document order), text = the page with everything else blanked so every line points into the .html file. A virtualKey keeps two modules of one page apart in the module key; ordinary files keep their key. parser/src/test/web-plumbing-tests.ts covers the web folder, the dist walk, brace comments and the inline modules, each checked to fail without its fix. Refs #1908
The oracle matched @scope rules unscoped as conditional at_rule:scope. It now evaluates the scope: subjects under a root matching the start selector and outside any limit below it, nearest root kept with its proximity (new row kind `scope`, read from web_styles.scope_root and scope_proximity); :scope and & name the root; a selector without them is relative to it; a prelude-less @scope in a <style> is rooted at the <style>'s parent; a non-exact bound gives scope_bound:<reason>. New case cascade/18. Refs #1908
…ow caps normalize.py reads var rows from the view web_var(use, def, page, status, reason) with use = the VARIABLE value_ref. tools/var_budget.py fails when web_var_visible exceeds 4 x (var() uses + custom-property declarations), web_var_scope exceeds 2 x the styles rows of var-using rules or 2M, web_var is materialized, or there is no var() use to measure. Wired as check=var_budget on the three var cases and on the 200-page scale case, which compares the view's count with the oracle's 4.5M rows again. Refs #1908
…arent list, disabled sheets
Per the iter1b rulings: an element whose id or attribute is bound at run
time (:id, x-bind:data-state, [attr.aria-expanded], id="row-{{ n }}")
gets one unknown dynamic_attribute row for each selector the binding may
complete (dynamic_attribute;dynamic_class when it needs both kinds), never
a match; & under '#app, .shell' is 1,1,0 for both; <link disabled> and
alternate sheets load conditional alternate_sheet. Cases cascade/19, 20.
Refs #1908
…sing G10 refs/09 (vendor animation shorthands), G11 nodes/04 now loads a sheet that targets the iframe fallback markup (never styled; the normalizer drops elements with inert=iframe_text and reports a styles row on one as an extra), G12 nodes/18 compares selectors (keyframe selectors are absent), G13 refs/05, G14 pages/05 (a site inside a sub-project with its own package.json; keys stay repo-relative). No known-missing file exists. Refs #1908
…I's --json cases/queries/01-admin-site is a hand-written dashboard site with 38 questions (37 graded, Q36 skipped_not_built until fragment hosts exist) over context, impact, path and link. tools/query_oracle.py derives every answer from the oracle's rows (expected/queries/..., each read by hand); tools/grade_query.py grades SET, SET>=, ORDER, CHAIN and TOP-k against the SPEC 6.2 row contract (at, role, status, rank; the JavaScript rows under other_languages.javascript), re-asks with --limit 0 when the answer says more > 0, and never counts a skipped template as correct. The runner prints query_ok per case; --oracle checks every derived answer still matches its reviewed expectation. Refs #1908
…ic attributes, written type names The bundle's web tables follow graph/test/web/tools/normalize.py (uid/file/line/col, element_uid, ...). Selector matching: static reasons per selector, initial-state pseudo-classes true only when the attributes say so, whole-selector unknowns (shadow_dom, column_combinator, selector_unparsed, implied_element) as one unknown row per page, dynamic class/attribute bindings as unknown rows, @scope as exact containment with scope_root/scope_proximity, HTML case-insensitive attribute values, SVG type names taken back as written (the parser lowercases them). Layer ranks and load order per SPEC 3.3; alternate/disabled sheets conditional. var edges stored as web_var_def/web_var_visible/web_var_scope with web_var a SQL view. Refs #1908
…kept it out) The repository-wide `oracle/` and `package-lock.json` ignore rules matched graph/test/web/oracle, so no commit on this branch carried the ground truth the suites are generated from. graph/test/web/.gitignore re-includes oracle/ and its lockfile (an exception to the no-lockfile rule: the oracle is a pinned measuring instrument, its transitive versions included) and keeps oracle/node_modules/ out. Refs #1908
… block with its whole list The grammar rejects the list's leading items as an ERROR inside the keyframe block list; the recovery that reads them as the next block's prelude never saw it, because the ERROR was lifted into its parts. Kept whole there now. Refs #1908
…nts, unknown rows only for undecidable selectors A trailing slash on a non-void HTML element is ignored by HTML; the following siblings become its content (the parser closes it at the slash). Declaration values drop their comments. web_unknown carries the selector/sheet/page unknowns; id references, loads and parse gaps keep their own tables. Refs #1908
…refs, var scope rows per (element, name) Parser: `@keyframes "fade"` is an @Keyframes named fade (the grammar takes only an identifier); the parser torture expectation that encoded the gap is updated. Engine: a link to `docs/` reaches docs/index.html; -webkit-/-moz-/-o-animation names become value references of their own (G10); web_var_scope holds one row per (page, element, name) and only for names something defines. Refs #1908
…r HTML and CSS (#1909); styled_by questions grade their own rows The web walk no longer skips dist/, build/ and out/ by name (the JavaScript walk still does), so refs/08 now loads dist/app.css as a match at load order 1 and the later links shift by one; a link into target/ keeps the not_indexed shape. No other expectation depended on the old walk. Q1, Q23, Q24 and Q28 all read the styled_by rows of one element; each expectation now names its filter (exact non-important / has conditions / state:* / important_count > 0) and grade_query.py applies it before grading. grade_query_selftest.py (run by --oracle) shows one full answer satisfies all four and that a dropped, corrupted or reordered row fails the question it belongs to. Refs #1908
…e SPEC 6.2 row contract
ax_web.py answers impact/path/context on a web graph (the verb scripts hand it a graph
whose run.language is web): rows {at, kind, role, status, reason, rank, ...} for
classes, ids, custom properties, pages, stylesheets, elements (page.html:LINE, the
cascade in §3.3 order), selectors, @Keyframes, @font-face, @layer, @container and
inline scripts; path over links, loads/@import, rules, styles and var(); context ranks
the files a task's words land on. tests/changed exit 3 (nothing to say). The front
door prints the web prose after the other languages' places. axiomcode-index indexes a
web graph's names as symbols (INDEX_VERSION 9); axiomcode-build counts pages and
stylesheets (web is the main language only when nothing else has files) and adds the
javascript graph for pages with inline scripts.
Refs #1908
…he page's markup Read from the JavaScript IR in the bundle (API name, receiver shape, literal argument): querySelector/All, getElementById, getElementsBy*, closest, matches, *Attribute, add/removeEventListener, createElement, insertAdjacentHTML, classList.*, style.setProperty, className=/innerHTML=/outerHTML=/textContent=/on<event>=/style.<prop>=, dataset.<k>, and jQuery's $()/jQuery() and its class, attribute, css, event and traversal methods (only on a jQuery receiver). Literal tokens split (.a #b div [data-x]); a non-literal argument is a non_literal row. Bundled/minified modules are not listed. No row names a web node. Kept out of the Soufflé rules: it needs no resolution and would cost a cold JavaScript engine compile per change. In a fanned-out --json answer the web graph's rows lead and the JavaScript graph's sit under other_languages.javascript (SPEC 6.2). Refs #1908
…is known by; nameless on* calls are not handler rows Refs #1908
…age, a .class/#id or a .js file answers with inline-script functions and DOM touches ext_module_provenance(module, file, qualified_name, provenance) and ext_method_module(method_id, module). On a JavaScript graph, impact <page.html> lists the functions of the page's inline scripts and on* bodies (role inline_script, named by ext_method_name) and its DOM touches; impact <.class|#id> the DOM touches whose tokens name it; impact <file.js> the usual answer plus its DOM touches. Rows of the JavaScript graph only; the fan-out puts them under other_languages.javascript. Refs #1908
… kept as BUNDLED, acorn-loose recovery Per the js rulings: normalize.py names a function COALESCE(ext_method_name.name, methods.name) and adds a provenance column from ext_module_provenance (PROJECT when a module has no row). The oracle keeps a site's own minified functions with provenance BUNDLED (their DOM touches stay outside the recall set) and falls back to acorn-loose 8.5.2 (pinned) when acorn rejects a script, so js/02's broken declaration is expected on both sides with no known-missing entry. New js/07: two inline scripts recovery can find no function in, beside a working one, so an invented function fails as an extra and the case still compares rows. js/01-03 and js/06 re-blessed (provenance column; js/06 gains its .min.js function). Refs #1908
… inline virtual path Refs #1908
…_indexed; SKILL.md names HTML + CSS Refs #1908
…L and CSS only) Reverts the G6 part of ae6c6d1a: the JavaScript front end no longer reads a page's inline <script> bodies and on* values as modules, the module key's virtualKey and the HTML parser's scriptSpans are gone, and the plumbing test for it is removed. The JavaScript parser, the module registry and the HTML parser are byte-identical to 3702fa6f again. The <ir>/web/ folder (G5) stays. Refs #1908
…nswers (scope: HTML and CSS only) Removes ext_dom_touch, ext_method_name, ext_module_provenance and ext_method_module from the JavaScript bundle (graph/bundle/dom-touch.ts), the JavaScript-graph impact on pages, .class/#id and .js files, and the web-first order of the fanned-out --json answer (reverting 39396eb2, aec9e2c2, f8924df8, b9d08f11, 381f2550 and that part of 54f127b9), and the build's javascript graph for pages with inline scripts. The web graph keeps a <script> as markup (src, resolved file, type, body range, body line count, inline_index) and a handler call by the name written (handler_index); nothing reads script text as JavaScript. Refs #1908
…other; fail a build whose engine has no .parallel marker The web branch adds a Soufflé program (graph/web) that run-souffle.sh looks up in the platform engine package, but build-engines never built it: a user without Soufflé would get 'has no web engine' and no web graph. web joins LANGUAGES and the Windows loop, so it is generated with -j 8, compiled with OpenMP on every platform and marked .parallel. The smoke step now fails when an engine lacks its .parallel marker (run-souffle.sh would solve it at -j 1) and runs each engine at -j 8, as a user's solve does. web stays out of ci.yml's install-and-run loop: that check counts call edges and runs the query verbs, and web has neither. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… x selectors and uses x definitions Two loops in the web bundle were quadratic in the site, not in its answers: - every page visited every selector of every sheet it loads, though most require a class or id the page does not carry (4,000 pages x 10,000 loaded rules = 40M visits); - every var() use walked every definition of its name (20k uses x ~1,800 defs). Selectors: each sheet is indexed once by a class or id its selectors require (a browser's rule hash). A plain page (one run, no composition, no dynamic class binding) visits the selectors whose key it carries plus those with no key, in sheet order; a skipped selector can only be tallied as loading, unmatched and missing on that page, and those tallies are added in bulk. Undecidable, :root and @scope selectors are never skipped, and a composed, extended or dynamic page still visits every selector. Vars: a name's definitions are grouped by owner once; a use walks owners, and whether a use sheet and a definition sheet share a page is asked once per pair. Output unchanged: every table identical (sorted rows) on all 132 web suite cases and on a generated 1,000- and 4,000-page site; the web suite passes 132/132. Bundle on the 1,000-page site 101 s -> 25 s (styles 39 s -> 10.8 s); 4,000 pages 202 s -> 84 s end to end. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…touched it) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dl), like every other engine's resolution HTML <-> CSS linking moves toward the engine: element tokens and the tree, a selector's compounds joined right to left (type, class, id; descendant and child), solved by the engine at -j 8 and exported as web_selector_match(selector, page, element) and web_selector_supported(selector) — relations a query or a pack can join, written to the graph as ext_web_selector_*. The bundle reads the engine's matches where they are exact: a plain page (no composition, no class binding) with no quirks mode, no mended <div/>, no upper-case HTML tag, and — for a selector with a type part — no SVG or MathML element (the parser lower-cases a type selector's name). Every other page and selector keeps the bundle's matcher, which also still turns each match into a status, the cascade and computed style. Output unchanged: every existing table identical on all 132 web suite cases (57 of them take matches from the engine) and on the generated 1,000- and 4,000-page sites. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt, resolution; tests under graph/test/web
- engine/projections/elements.dl, selectors.dl: column reads of the HTML and CSS facts
- engine/containment/ownership.dl: rules nested in a style rule
- engine/resolution/loads.dl (+ web_page_sheet), selectors.dl (was match.dl), values.dl;
headers in the engines' 'Resolution · NAME' form, and loads.dl no longer says selector
matching is the bundle's
- graph/web/test/{cli-smoke,includes,violations}.sh move to graph/test/web/, beside the suite,
as every language keeps its tests; bin/axiomcode follows
- parser/tools/web-corpus-bench/BASELINE-2026-10-07.md removed: a dated, generated snapshot
Unchanged output: every table identical on all 132 web cases; web suite 132/132, cli smoke 36/36,
include checks 9/9, violation checks 101/101.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, its CLI/violation/include checks, its declarations against the parser schema
- the suite matrix gets a web leg: graph/test/web/run-tests.sh (132 oracle-gated cases), then
graph/test/web/{cli-smoke,violations,includes}.sh; AXIOMCODE_ENGINE points the front door
(the web query cases) at this checkout; tests/run.py has no web cases, so that step skips web
- web joins the decls_base drift check; it stays out of check_staging (it stages no library)
- run-tests.sh measured a build's peak memory with BSD 'time -l', which fails every case on
Linux: it now uses GNU 'time -v' there (kB) and 'time -l' on macOS (bytes), and the leg
installs 'time'
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… check and the nightly e2e-install.sh checked a call graph's edges and the call-graph verbs, which a web graph has neither of: for web it now checks that the installed package used its packaged web engine and wrote pages, selectors, style rows and engine matches. ci.yml and nightly.yml run it on a web fixture (cases sit one level deeper) whose selectors the engine supports. Checked locally: packed tarballs installed into an empty project, souffle hidden, packaged darwin-arm64 web engine used; 1 page, 6 selectors, 12 style rows, 7 engine matches. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts; path reaches a class only selectors name
- impact (no name), CLI and MCP: the web graph maps each hunk of an edited .html/.css to the element or rule it is
in and answers for those, beside the call graphs' answer (text and --json), against the same baseline `changed`
uses; it says when the graph predates the edit (by content, ax_fresh's file table). Before: "your edits: none".
- path: a .class or #id endpoint is the elements carrying it and the selectors naming it, so `path page.html .x`
reaches a rule for a class no element carries instead of "nothing named '.x'".
- context: a page named by a number or a file name ("the 404 page") is found.
- changed / tests: pages and stylesheets are named as the web graph's, not as files outside every indexed
language; tests answers in text when the JSON answer has no places (it printed the raw document).
- index: the web graph's summary line counts pages, stylesheets, selectors and styled elements (it was empty).
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nswers), 692 files to 294 A case's site was a directory of a case.conf and a few small pages and stylesheets; it is now one text file the runner unpacks into .work/cases/ (tools/cases.py, byte-exact: binary or CR files go base64, a file without a final newline is marked). The engine and oracle runs read the unpacked tree exactly as before; CI and the nightly unpack their web case. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…too (.github/e2e/web) The install check stopped at "the web graph has rows" for web. e2e-web-queries.sh is e2e-queries.sh's twin for a site: impact on a class, a stylesheet and a page, path page -> imported sheet, context, --json, the same three verbs where exec does not replace the process (#1640), then an edit to a rule (impact with no name) and tests (exit 3, none). Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
web: HTML and CSS engine (0.2.0)
…s them 0.1.10 passed its release e2e on Windows while 43 of the query cases' 1,844 checks failed there: the e2e is one case per language. Every cause is how Windows writes paths and command lines, or how it holds files; none is platform-specific code. Paths: repository-relative paths are written with `/`, as the graph stores them. - parser: the Python and C# analyzers recorded `pkg\changed.py` in the IR, so rules joining a module's directory to a string (importlib's SourceFileLoader, Django's include()) matched nothing, and C# derived test attributes were missed. - query scripts: os.path joined and normalised graph paths with `\` (runner setupFiles/globalSetup, spawned scripts, the JS/TS import resolver, the freshness snapshot), so tests reached through a file were not linked. posixpath now, the idiom axiomcode-test-impact already used. - path/impact: an absolute file:line under the repository was refused as outside it (a `root + '/'` prefix test); commonpath on normcased paths. Arguments: a native program cannot hand Git Bash an argument holding ' or ": msys parses the command line by its own rules, so `context "the user's cart"` lost every argument after the apostrophe and a quoted string arrived as \Key\. On Windows the CLI, the MCP server and every build Python starts pass them in AXIOMCODE_ARGV (ax_exec.bash_argv); the bash entry points turn them back into "$@". Elsewhere the command line is used as before. Build lock: on Windows it locked nothing (Git Bash's fd 9 is not a descriptor in a native python), so a refresh and a second build of one repository could run at once. A helper (ax_fresh.py hold) now holds a real lock for the build's lifetime; building() sees it and a second build waits. POSIX keeps flock. Tests and the gate: - tests/run.py starts the CLI as the product does (Git Bash found by find-bash.js, MSYS=noglob, arguments via bash_argv), reads and prints UTF-8, uses the sqlite3 module, and waits for a case's background refresh before removing its graph. - tests/windows_argv.py: the argument hand-over through both entry points, with the command line as control. - no_symlink / no_exec start Git Bash and UTF-8 Python as the product does. - the release e2e on win32-x64 now runs every query case against the installed packages, and the Windows-only tests (.github/scripts/e2e-cases.sh). Verified: Windows VM, every language's query cases (1,844 checks), the Windows-only tests and the gate script; repeated asserted-links runs 25/25. Linux: the five engine suites, the query cases and the standalone tests identical to dev (51 of 51 results). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
relpath raises across drives on Windows, so a --library whose compiled IR sits in the user cache on C: while the repository is on D: (as on GitHub's runner) failed the whole index. axiomcode-index and axiomcode-graph read it as outside the repository, as a `..` path is; a link or a changed file given absolutely on another drive is kept as given. no_exec's control starts Git Bash, not a bare `bash` (WSL on GitHub's image). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ightly runs every case Every query case on Windows took 37 of the e2e job's 50 minutes, against 2-6 for the smoke test on every other platform. A release now runs the 39 case names that have failed on Windows (.github/e2e/windows-cases.txt: 63 of 356 case directories, every language), about 7 minutes; the nightly (fresh) still runs every case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The benchmark section restated the test-selection and call-resolution numbers already shown under What it does, and the agent-support table repeated every install and uninstall command from Installation. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
docs(readme): drop sections that repeat the top of the page
Windows: the query cases answer as on Linux, and the release gate runs them (0.2.0)
0.2.0 already carries every 0.1.11 change: #1949 cherry-picked them. The merge records 0.1.11 as part of 0.2.0's history, so the 0.2.0 release merges into dev and main without conflicts. Every conflict (version files, ax_fresh.py, ci.yml) resolves to 0.2.0's side, which holds the same fix adapted to 0.2.0; the merged tree is identical to 0.2.0's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge 0.1.11 into 0.2.0 (history only, no change to the tree)
swapnilpaliwal-sd
requested review from
JaredHLZhang,
Whua689 and
suyashpaliwal26
as code owners
October 14, 2026 20:31
…s them Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
readme: HTML and CSS in the language icons
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.
Additions
Features
axiomcode graphis back: it draws the codebase as one interactive page (directories, files, types and methods, with the call edges between them and each edge's tier). It uses the graph the index already built and rebuilds first only when a source file changed, then prints the page's path. It's a page for you, not an MCP tool for the agent (a 1,304-method Python library draws in 0.1 s) graphaxiomcode reportrenders the record as an HTML page, andAXIOMCODE_ASSISTS=offturns it off pluginImprovements
path X '*'gives the total reached and the count per hop, and a name that matches N declarations says so instead of reading as one (path main '*'on a tree with 22mains) pluginAXIOMCODE_REFRESH_BATCHstill overrides it refreshBugs
--librarythat keeps its declarations in a build directory staged almost none of them (a root.d.tsre-exporting./dist: 78 → 8,238 methods; declarations only underdist/types: 0 → 218). Calls into such packages now resolve to the library typescript