Skip to content

0.1.2: CLI end to end on every platform, one target spelling, Windows hardening, AxiomCode bot - #1367

Merged
swapnilpaliwal-sd merged 11 commits into
devfrom
release/0.1.2
Sep 26, 2026
Merged

swapnilpaliwal-sd merged 11 commits into
devfrom
release/0.1.2

Conversation

@swapnilpaliwal-sd

Copy link
Copy Markdown
Contributor

0.1.2

Makes npm i -g @axiomcode/code-graph work end to end on macOS, Linux and Windows, and gives every CLI verb one way to name a declaration.

CLI and query fixes

Windows

CI

Verified

  • Plugin suite: 234/236 (the same 2 marked pending as on dev).
  • Standalone tests all pass, including the new tests/no_symlink.py.
  • New cases fail on dev and pass here: typescript/dotted-target, typescript/separator-collision, javascript/dotted-target, javascript/imported-class.
  • Windows Server 2022, as a non-admin user, 0.1.1 plus these changes: all five languages index, and answer impact (every spelling), path, context and changed --impact; CRLF sources and a path with a space work; the pipeline runs from a directory holding git.exe/py.exe; 24/24 expected edges.
  • The extended e2e run locally on darwin-arm64 against the packaged engines: all five languages pass; against 0.1.1 it fails on the dotted TypeScript target and the no-symlink impact.

No rule or .dl file changes, so every engine id and query-binary id is unchanged.

Closes #1359
Closes #1360
Closes #1361
Closes #1363
Closes #1364
Closes #1332
Closes #1365
Closes #1366

…erpreter (#1359)

An Intel python3 on an Apple Silicon Mac runs under Rosetta and reports
x86_64, so dl_program looked for engine-darwin-x64 while npm had
installed engine-darwin-arm64, and impact failed without Souffle. A bash
started from it inherited the translation, and run-souffle.sh's uname -m
made the same choice for the rebuild.

On macOS, hw.optional.arm64 now decides (sysctl by full path, since
/usr/sbin is often not on a hook's PATH). Both lookups also fall back to
the same OS's other architecture, because npm installs exactly one
engine package per machine.
…e first (#1360)

Each front end spells a qualified name its own way (Java/C# pkg.Owner.m,
Python pkg.module.f, TypeScript src/util#square, JavaScript src/util.square),
so `util.square` resolved in Python and failed in TypeScript, where the
lowercase dotted shape was then handed to the config-key path and died with
"looks like a configuration key".

- The resolvers (path, and impact's types/fields, which path's methods
  lookup serves) now also compare names with / # :: $ read as `.`, on both
  sides. This runs only after the name as written matched nothing, so every
  spelling that resolved before resolves to the same declaration now.
- A dotted name that fits declarations differing only in separators
  (a/b#c, a.b#c, a#b.c) is refused, listing each exact spelling; each of
  those still resolves to its own declaration.
- A lowercase dotted name goes to the config-key path only when the graph
  has configuration facts or its last segment names nothing the code
  declares; otherwise a miss names what is close.
- A qualified name whose last segment the client declares no longer falls
  through to "type used by name", which answered zzz.square with every
  reference to `square`.
- changed hands hooks the full dotted name of the edited declaration
  (target), keeping the short name in the printed hint (shown_target), so a
  hook's impact no longer answers for every declaration of the same name.
- The dotted comparison is prefiltered with LIKE on the last segment, which
  keeps a miss on a million-symbol table at ~0.06 s instead of ~2.3 s.

Cases: typescript/dotted-target, typescript/separator-collision,
javascript/dotted-target. Help and SKILL.md say separators are
interchangeable.
…ariable (#1361)

all-javascript-variables.csv carries a binding for every declaration: a
`function f` (FUNCTION_DECLARATION_HOISTED), a `class C` (CLASS_TDZ, twice)
and `const { C } = require('./m')` (CONST_BLOCK_TDZ with an importLinkHash).
The index kept all of them as variable/const rows beside the function or
class itself, so `impact C` on nearly every imported class refused as
"declared as more than one kind", and `changed` reported an edited function
as a field, which sent the edit hook's impact to the wrong declaration.

Only IMPORT_BINDING was excluded. Function and class bindings and bindings
with an importLinkHash now are too, as Python's index already excludes
FUNCTION_DEF, CLASS_DEF and IMPORT. Case: javascript/imported-class.
…fresh (#1363, #1332, #1364)

impact, and path's Datalog backend, staged fact files with os.symlink,
which an unelevated Windows user may not call (WinError 1314): every
impact, test-impact and changed --impact crashed for an ordinary user,
while CI's elevated runner passed (#1363). Facts are now staged by
symlink, else hard link, else copy. tests/no_symlink.py denies
os.symlink on any OS and fails on the old code.

Windows starts a program named without a path from the current
directory before PATH, and so does Node's spawn. The launcher's
`git --exec-path` and python probes therefore ran a git.exe / py.exe
lying in the working directory: an installer that waited for ever,
which was the pipeline "stall" (#1332), and a planted binary in a
repository would have run. Bare names are resolved over PATH only
(mcp/which.js), the probes time out, and the launcher sets
NoDefaultCurrentDirectoryInExePath=1 for everything below it.

#1364:
- dl_program also looks next to npm's axiomcode.cmd wrapper for the
  engine package, which a plugin installed outside the npm tree needs.
- The background refresher starts bash with CREATE_NO_WINDOW.
- The hooks' relpath no longer raises across drives.
- The dispatcher exports AXIOMCODE_BASH from the Git Bash running it.
- Baseline library roots are split on commas only.

Verified on Windows Server 2022 as a non-admin user: all five languages
index, impact, path, context and changed --impact; CRLF sources and a
path with a space; the pipeline from a directory holding git.exe and
py.exe; MCP initialize and tools/list; 24/24 expected edges.
…release/0.1.2

# Conflicts:
#	plugins/axiomcode/skills/axiomcode/scripts/axiomcode-path
… app (#1365)

GITHUB_TOKEN always acts as github-actions[bot], so v0.1.1 reads
"github-actions released this" and its tag's tagger is github-actions.
An org-owned GitHub App's token acts as <app-slug>[bot] with the app's
avatar.

.github/actions/bot mints that token per run from the repository
variable AXIOMCODE_BOT_APP_ID and the secret AXIOMCODE_BOT_PRIVATE_KEY,
and returns it with the matching git name and noreply email. Until they
exist it returns github.token and the github-actions identity, so this
can merge before the app is set up.

Used by: release.yml's tag-and-draft step and the main -> dev sync
merge with its conflict issue; the nightly's failure issue; main-guard's
direct-push issue. Pushes go to an explicit x-access-token URL so the
checkout's persisted GITHUB_TOKEN header is not what authenticates them.

A push with an app token starts workflows. Nothing runs on a tag push
and a draft release does not trigger publish-npm, so the one new run
is CI on dev after the sync merge.
)

The five-platform e2e installs the release binaries with no Souffle and
answered index, impact, path (both backends), path --every, context,
changed and test-impact. It now also asks, on the same fixtures:

- impact by the graph's own qualified spelling, by the dotted form every
  language accepts, and by file:line (read from the built graph, not
  written into the fixture), so #1360 cannot come back unnoticed;
- impact --json, which must parse and name the caller;
- path '*' <leaf>;
- impact and the Datalog path with os.symlink refused, as for an
  unelevated Windows user; the runner is elevated and never saw #1363;
- on Windows, impact run from a directory holding git.exe, python.exe,
  python3.exe and py.exe (copies of cmd.exe), for #1332;
- changed --impact, graph --out, help impact, and --version against the
  installed package's version.

Run locally on darwin-arm64 against the packaged engines: all five
languages pass; against the 0.1.1 tarball the TypeScript dotted target
and the no-symlink impact fail, as they should.
@swapnilpaliwal-sd
swapnilpaliwal-sd merged commit 74eeef5 into dev Sep 26, 2026
11 checks passed
@swapnilpaliwal-sd
swapnilpaliwal-sd deleted the release/0.1.2 branch September 26, 2026 08:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment