Repository navigation
Releases
Graphicle 0.1.13
Every crate is at 0.1.13, and graphicle --version prints
graphicle 0.1.13 (core). The Python and TypeScript SDKs are at 0.1.13 too.
After upgrading
- Run
graphicle synconce in each project, as after 0.1.12: the saved
graph and the query file are keyed to the program's build, so the first
sync writes both again. - The first
graphicle-graph updateafter upgrading is a full one: the
extraction cache's schema moved on, and the early stop below needs a
record that only a full update writes.
Faster updates
graphicle-graph updatestops early when nothing has changed since a full
update that itself changed nothing. That update records, in
.graphicle_build_state.jsonin the output folder, the size, modification
time and (on Unix) status-change time and inode of every file it scanned,
of the configuration files around the project, and of every file the
extractors read outside the scan, such as a C header in an ignored folder
or a Sphinxconf.pyabove the project. The nextupdatescans the
project, compares, and if nothing differs prints "No relevant changes" and
keeps the graph. Anything it cannot prove the same takes the full update:
a file edited while an update runs, a JavaScript workspace above the
project,--precise, or an extractor that walks the tree without the
ignore rules (Pascal and C# project files). Seedocs/configuration.md.- Measured on one cloud machine with 8 CPUs and 8 workers, an update with
nothing to change took, as the median of 5 runs, 15.7 s on kubernetes
v1.37.1, 1.02 s on react v19.3.0 and 0.25 s on redis 8.10.2, against
164.8 s, 22.6 s and 3.40 s for 0.1.12's full update (median of 3), with
the same outputs. - A file whose content always fails to extract (a JSON or YAML file over the
size limit, a YAML file the parser refuses, a binary Delphi form) no
longer keeps the early stop away; a read error, a timeout or an extractor
that stopped still does.
Project wiki
graphicle wiki buildhas a model write one article per area of the code,
with an index of one-line summaries, in.graphicle/wiki/written/. Each
paragraph cites files and lines, and a citation must fall on lines the
model was shown, or the paragraph is dropped and counted.
graphicle wiki updaterewrites only the articles whose code, docs or
reviewed memories changed. Calls are capped by--max-cost(1 USD by
default) and the profile's caps, logged ingraphicle usage, and priced
first with--dry-run. Captured sessions are never sent.
graphicle wiki hook onadds an optional post-commit update with its own
cap. Seedocs/wiki.md.graphicle wiki checklists, with no model, doc passages whose named code
changed since they were written, stale memories, wiki citations that no
longer hold and areas of the code with no doc or article. With a model it
proposes corrections: a doc's as a patch file, a memory's in the approval
queue. It never edits your files.- The wiki was tested against local stand-in models; no live model run is
part of this release.
Fixes
- Doc links flag a passage whose named function changed after the passage
was written, ingraph.doc_linksand as a note on recall excerpts. - An output folder given by a relative path that leads outside the project
(GRAPHICLE_OUT=../out) now gives one graph, as an absolute one has since
0.1.12. - A deleted Office document takes its nodes with it, wherever the output
folder is. extractafterupdateno longer warns that it kept nodes "fail-closed"
for a converted Office document the scan lists.
Docs
- The README's benchmarks gain a chart of an update with nothing to change,
0.1.13 against 0.1.12, with the numbers above.
Packaging
server.jsonat the repository's root is the MCP Registry entry of
0.1.12, the latest listed release (it named 0.1.11).deny.tomlin graphicle-graph and graphicle-memory ignores
RUSTSEC-2026-0441: pin-utils, which the AWS SDK of the bedrock feature
brings in, is unmaintained, with no known vulnerability.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.13/install.sh | sh -s -- --version 0.1.13On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.13'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.13/install.ps1 | iexEach archive's SHA-256 sum is in SHA256SUMS and beside it in a .sha256 file.
graphicle.exe and graphicle-graph.exe in the Windows archive carry a signature from a SignPath test certificate. Windows does not trust that certificate, so it treats them as unsigned programs and may warn before it runs them. Code signing policy
Graphicle 0.1.12
Every crate is at 0.1.12, and graphicle --version prints
graphicle 0.1.12 (core). The Python and TypeScript SDKs are at 0.1.12 too.
Everything new in 0.1.12 was written during Meta's Global AI Developer
Hackathon.
HACKATHON.md
lists it with when it was written.
After upgrading
- Run
graphicle synconce in each project, as after 0.1.11: the saved
graph and the query file are keyed to the program's build, so the first
sync writes both again. - On Windows, if you set
GRAPHICLE_MAX_WORKERS=1to get past the crash
below, remove it: extract and update use all their workers again.
Fixes
- On Windows,
graphicle-graph extractandupdateno longer exit with
0xC0000005 (an access violation) once they split their work across worker
threads, which a file with a few tens of symbols was enough to start. The
crash came from mimalloc 3.3.2, most likely microsoft/mimalloc#1306, so
the Windows programs now use the system allocator, as the macOS programs
have since 0.1.1. Linux keeps mimalloc. Reported by Michael George in #18,
with the cases that reproduced it. graphicle fix: a second run on the same issue that starts within the
same second as the first takes the next free worktree folder (-2,-3
and so on), as the branch name already did. Before, it stopped with git's
"already exists".graphicle fixapplies the model's edits to files whose lines end in
CRLF, as Git for Windows checks them out, and those files keep CRLF.
Before, every edit whose search text spans a line break was refused there
with "the search text is not in the file as it is now". An edit takes the
file's line breaks when all of them are CRLF or all are LF; a file with
both, or with none, takes an edit as it is written (docs/fix.md, step
4).- With the output folder outside the project, given by an absolute path in
GRAPHICLE_OUT, the nodes of Office documents no longer depend on where
that folder is. Each.docxand.xlsxfile is converted to a Markdown
file in the output folder, and the ids of its nodes were taken from that
file's path, so two output folders gave two graphs with the same counts;
the 0.1.11 benchmarks found three graphs of pandas this way. The ids now
come from the converted file's name, which is hashed from the document's
path in the project, so they change once, at the first
graphicle-graph update, orwatchor hook rebuild, after upgrading.
Graphs without Office documents or Google Workspace shortcuts, and graphs
in the default output folder (.graphiclein the project), are unchanged.
An output folder given by a relative path that leads outside the project
(../out) still names them by that path. graphicle-graph watchof a subfolder (watch src) keeps the nodes of
Office documents in its incremental rebuilds. Before, with an output
folder more than three folders up, it dropped them until the next full
update.
Dependencies
- zip 9.2.2 and calamine 0.38.0, for RUSTSEC-2026-0367, -0368, -0369 and
-0429 and GitHub's zip advisories of 28 and 29 October, one of them
critical (GHSA-m665-v7pm-7grj, fixed in zip 9.0.5, the lowest zip the
crates now accept).deny.tomlno longer makes exceptions for them, and
the third-party licence pages list the new versions. - calamine 0.38 reads two kinds of legacy
.xlsfile more correctly: the
rows of an embedded chart no longer appear in its sheet, and BIFF5
rich-text strings keep symbols such asβ’andβ.
Hosted demo
demo/modal_app.pyruns the hosted demo on Modal: an image with the
v0.1.10 release's binary and the checkouts, a Volume with the data folder,
andserver.pyscaling to zero, live with the Meta key's secret or,
without it, showing the recorded answers (demo/README.md, "Modal").
Docs
- The README opens with "Graphify, ported to Rust. Plus memory." and the
live flow from a bug on the screen to a tested fix, and gives the
13-codebase results as bar charts of time and peak memory. docs/benchmarks.mdgives Graphicle 0.1.11 against Graphify 0.9.100 on
one Linux machine: updates after 30 recent commits in three repositories,
and the time and peak memory of three operations on 13 codebases. Its note
on pandas' three graphs now gives their cause, fixed above.- HACKATHON.md calls the pack,
ask --packandplanwritten before the
kickoff first drafts, and says that every change to them after it is event
work. docs/fix.mdandgraphicle fix --helpsay that the test command runs
withcmd /Con Windows, notsh -c, so a test command written for sh
does not run there as it is written;docs/flow.mdand
graphicle see --helpsay the same of its driver.
Packaging
server.jsonat the repository's root is the MCP Registry entry of
0.1.11, the latest listed release (it named 0.1.10).graphicle-graph's NOTICE says that the program uses mimalloc as its Rust
allocator on Linux only.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.12/install.sh | sh -s -- --version 0.1.12On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.12'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.12/install.ps1 | iexEach archive's SHA-256 sum is in SHA256SUMS and beside it in a .sha256 file.
graphicle.exe and graphicle-graph.exe in the Windows archive carry a signature from a SignPath test certificate. Windows does not trust that certificate, so it treats them as unsigned programs and may warn before it runs them. Code signing policy
Graphicle 0.1.11
Every crate is at 0.1.11, and graphicle --version prints
graphicle 0.1.11 (core). The Python and TypeScript SDKs are at 0.1.11
too.
Everything new in 0.1.11 was written during Meta's Global AI Developer
Hackathon.
HACKATHON.md
lists it with when it was written.
After upgrading
- Run
graphicle synconce in each project, as after 0.1.10: the saved
graph and the query file are keyed to the program's build, so the first
sync writes both again.
graphicle fix
- A long test output keeps the lines that report failures. When a round's
test output is longer than the 6,000 bytes that go back to the model, the
round keeps the lines that report failures from the part that is cut
(lines withFAIL,Γ,AssertionError,Error:,panicked,
Traceback,error[E0425]:,expectedorreceived, and the like),
each once and at most 2,400 bytes of them, then a[...]line and the
output's end. Before, only the end was kept, so a runner that prints its
failures before a long dump, as vitest does before the DOM it compared,
sent the model the dump without the assertion. While the test runs, each
output stream holds up to 128 KiB, then drops whole lines from its start
down to about its last 64 KiB; the lines that report failures are read in
all that it holds and in what it drops, so an output of 64 to 128 KiB
keeps an assertion it printed first. Terminal colour codes are removed
from the output; the values of the model keys are still hidden in it. - The next round reads the files that the failure and the model name. After
a failed round, the next round's request adds, after the diff, the files
that the test output (or the reasons the edits were refused) names, that
the model's explanation and edits name by path, and that define a code
name the explanation gives (found in the project's code graph), when the
pack does not hold them whole: at most 6 files and 24,000 tokens a round,
counted as the pack counts, read from the worktree, and only files the
project's last sync holds, inside the project. Without--budget, the
files take only the room the round's request has left after the pack, so
the round is sent with the same pack and its start can stay in the
provider's prompt cache. The instructions tell the model that a file it
names this way is added to the next round. Each round's JSON report
lists what its request added and why undercontext, with what was left
out; the readable report lists the added files under each round. A round
whose request does not fit the model's input limit with its files goes
without them: the readable report lists them as not added, and the next
round adds them only when the failure or the model names them again.
Before, a file the pack did not hold stayed out of every round. See
docs/fix.md.
Fixes
graphicle askanswers when the model cites more passages than an answer
keeps. An answer keeps at most 12 citations and 20 unanswered parts (and,
with thegrounded-v3contract, its limit of reading notes). A reply
with more, which a broad question can draw, failed the job with "Model
output does not match the workflow contract". The reply now keeps its
first 12 citations and first 20 unanswered parts, and the job's result
gives, undertrimmed_to_cap, how many the model returned and how many
were kept. An answer's text never refers to a citation by its number, so
nothing in it points at a citation that was cut.--workflow reflect
keeps its final reply the same way. (reported in #17)graphicle ask --workflow reflectgoes on when the model asks to read a
source the answer does not have, such as a path it guessed from the code
or a file thatsyncleaves out. The read is skipped, the job's trace
records it with"unavailable": true, the next step reads that note, and
the answer comes from the sources that could be read. Before, the job
failed with "Reflection requested an unavailable source". (reported in
#17)graphicle ask --pack,plan,fixandreviewuse a model key saved
in the app (graphicle open, then Connections), asaskanddoctor
do, for the call and for the provider's token count. Before, they read
the key only from an environment variable and failed with "Provider
credential unavailable; workspace credentials require the service
worker". A key in an environment variable is read as before.fixhides
a key saved in the app in the test output that goes back to the model
and into its report, as it hides the keys in variables. (reported in #17)
The flow and its docs
demo/flow/flow.pyuses Muse Spark for computer use by default
(--see-model spark). On 30 October 2026 Muse Wonder answered the
computer tool with HTTP 400 "Unsupported tool type" on the key we tested,
and Muse Spark 1.3 ran it.docs/flow.mdanddemo/README.mddescribe
the live runs. The Muse Code docs describe the plugin's first live
session (Muse Code 1.4.14, 30 October 2026, with 0.1.10's plugin): Muse
Code ran four of its six hooks and called itspacktool, but stopped its
session-start hook, whose output passed the 16,384 bytes Muse Code takes
from a hook, so the session started without Graphicle's session-start
context (fixed below, under Muse Code plugin).- The flow's check keeps its budget when the fix runs on another profile.
With computer use on Muse Spark and the fix on Muse Wonder, the check took
the computer-use profile's cap less everything the run had spent, so a fix
that cost more than that cap left the check a cent and the binary refused
its call. The check's budget is now its profile's cap less that profile's
own calls.
Muse Code plugin
- The session start stays within Muse Code's limit on a hook's output. Muse
Code takes at most 16,384 bytes of what a hook prints and reads none of a
longer output: in the plugin's first live session (Muse Code 1.4.14, 30
October 2026), the session start printed more than that, Muse Code
stopped it, and the session started without Graphicle's session-start
context. The session start now prints at most 14,000 bytes for Muse Code.
When the map and the memories do not fit together, it leaves out parts of
the map first, in the order a pack over its budget drops them (its least
connected files first, then its documentation, folder map and
architecture summary), then the whole map, then the memory's last lines
(recent turns before memories), never the line on when to use Graphicle,
and ends with a line that says what was left out and which tool returns
it. Claude Code and Codex get the same output as before. This is tested
against the stand-inmuseprogram, not yet in a live session. - Muse Code's session map is 2,500 tokens by default and at most 3,500
tokens (8,000 and 100,000 before), and it lists the most connected files
first.
Measured on 31 October 2026, a map of 2,500 tokens took 8,464 bytes for
Graphicle's own Rust code and 10,580 bytes for its Python tools, which
leaves room for the memories; at 8,000 tokens the same maps took 27,551
and 33,570 bytes, more than Muse Code's limit on their own.
Benchmark kits
- The whole-repository benchmark's model runs, which 0.1.10's kit was
written for, were made on 30 October 2026. Their results are not in
this release. bench/whole-repo/run.pygains afireworksprofile for Muse Spark Open
on Fireworks' serverless API (chat completions, key from
FIREWORKS_API_KEYor--key-file). The run's session id goes in the
x-session-affinityheader and theuserfield, the two hints Fireworks
documents for its prompt cache, and the cached tokens come from the usage
or, when it has none, from thefireworks-cached-prompt-tokensheader.
prices.jsonhas the model's Fireworks prices.bench/muse-code/reads the events of Muse Code 1.4.14: an event's name
is inpayload_type, the model calls and tokens come from the one
run.usageevent at the end of a run, and the answer from
run.terminal.completed. Before, the kit counted no calls and no cost
for a 1.4.14 session. With 1.4.14 the kit's cost caps (--run-cap,
--day-cap) can act only after a run, since the usage arrives at its
end.
Packaging
- libz-sys 1.1.31 (from 1.1.29, through flate2). RUSTSEC-2026-0418, a build
script that prints the whole build environment when built with cc 1.6.0
or later, no longer applies, andcargo denychecks every crate without
an exception for it. The locks keep cc 1.4.7.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.11/install.sh | sh -s -- --version 0.1.11On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.11'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.11/install.ps1 | iexEach archive's SHA-256 sum is in SHA256SUMS and beside it in a .sha256 file.
graphicle.exe and graphicle-graph.exe in the Windows archive carry a signature from a SignPath test certificate. Windows does not trust that certificate, so it treats them as unsigned programs and may warn before it runs them. Code signing policy
Graphicle 0.1.10
Every crate is at 0.1.10, and graphicle --version prints
graphicle 0.1.10 (core). The Python and TypeScript SDKs are at 0.1.10
too.
Everything new in 0.1.10 was written during Meta's Global AI Developer
Hackathon.
HACKATHON.md
lists it with when it was written.
After upgrading
- Run
graphicle synconce in each project, as after 0.1.9. The saved
graph and the query file are keyed to the program's build, so the first
sync writes both again. Until then a question reads the code graph from
the store, and on a project of 2,000 files or more the prompt hook gives
only the files that define the code names a prompt gives. - The first check of a folder that an earlier version synced finds its
HTML files changed, though nothing on disk changed, so the next command
that reads the project (such asgraphicle pack,ask,contextor
status, or an MCP tool call) syncs them again as they are (see the
first bullet of Fixes). A folder with more than 200 such files, or one
whose sync is slow, gets a note to rungraphicle syncinstead; with
freshnessset tooff, rungraphicle syncyourself. - A reviewed project memory that cites a folder's HTML file goes stale
after that sync, because the page's stored text changes from its words
to its markup. Review those memories in the app (graphicle open,
under Memory). - In the GitHub Action of
graphicle review, setgraphicle-versionto
0.1.10, andgraphicle-sha256to the SHA-256 of 0.1.10's archive for
the runner (in the release'sSHA256SUMS): the escaping under Fixes
comes from the program the Action installs.
Whole-repository packs
-
Packs in the standard layout hold their top-ranked files whole more
often. In a pack of 32,768 tokens or less, the first ranked file goes in
whole when its estimated size fits in half the budget; in a pack of
131,072 tokens or more, the first two go in whole when each one's
estimated size fits in a quarter of it. The estimate comes from a file's
size in bytes, not from the tokenizer. This changesgraphicle pack, the
MCP server'spacktool (32,000 tokens by default), and the packs of
ask --pack,planandfix, which use the standard layout by default.
The default budget ofgraphicle pack, 128,000 tokens, stays below the
second tier, and so do the packs for a model with a 128K window, unless
a calibration from earlier calls raises their budget past 131,071
tokens. A pack with pinned passages (fix --focus,review) keeps the
per-file caps for every file, so each pinned passage keeps its room.
This rule leaves packs of 32,769 to 131,071 tokens, and the cache
layout, as they were. -
Measured without a model, as the share of questions (tasks, on
SWE-bench Pro) whose pack holds every line that the reference fix
changes, with tokens counted by the Muse Spark Open tokenizer: 0.1.9
against a candidate build of 0.1.10 with both changes (whole top files,
and a folder's HTML files kept as they are, under Fixes), made before
this release's last fixes, at budgets of 16K to 1M tokens (16,384 to
1,015,808; the 128K budget is 131,072 tokens, in the second tier). A
build with those fixes, run again on the development questions, matched
the candidate except for one question at 256K, whose pack left out one
file the fix changed.- On the 90 held-out questions of the whole-repository benchmark
(pytorch, vscode and elasticsearch, never tuned on): 26.7% to 34.4% at
32K, 41.1% to 48.9% at 128K, 47.8% to 52.2% at 256K, 53.3% to 58.9% at
512K and 58.9% to 64.4% at 1M; unchanged at 16K (21.1%) and 64K
(33.3%). The mean share of the fix's files inside the pack (whole, or
as excerpts or outlines) moved by +1.7 points at 16K, -0.3 at 128K and
-1.1 at 512K, and not at the other budgets. - On 633 tasks of SWE-bench Pro's public set (at 1M, the 505 whose files
hold more than 1M tokens): 10.3% to 15.0% at 16K, 16.7% to 20.4% at
32K, 29.1% to 29.2% at 64K, 40.8% to 42.3% at 128K, 51.5% to 52.8% at
256K and 66.5% to 68.3% at 1M, where file-level BM25 holds every
changed line in 14.2%, 19.0%, 25.9%, 32.7%, 41.5% and 58.0% of tasks.
The share of tasks with every file the fix changes inside the pack (any
of its text) moved by -0.8 points at 16K and at 128K, -0.3 at 32K and
-0.2 at 1M, and not at 64K and 256K. Counting only the files the pack
holds as text, not as an outline, it fell by 2.1 points at 16K (95%
interval -3.5 to -0.6) and by 0.3 points or less at the other budgets.
A diagnosis of 0.1.9 on these tasks chose the directions of this
change, though not its settings, so they are not an untouched test. - On the 200 development questions it was tuned on (kubernetes,
home-assistant, angular, keycloak and godot): 32.0% to 36.0% at 16K,
48.0% to 51.0% at 32K, 70.0% to 72.0% at 128K, 76.0% to 77.5% at 256K,
79.5% to 81.0% at 512K and 81.0% to 82.5% at 1M; unchanged at 64K
(57.5%). The mean share of the fix's files inside moved by -1.0 point
at 32K and -0.5 at 1M, and by 0.2 points or less at the other budgets.
The tables are in
bench/whole-repo/results-lines.md
and
bench/swe-bench-pro/results-e1l.md. - On the 90 held-out questions of the whole-repository benchmark
Fixes
- A project folder's
.htmland.htmfiles are kept as they are on
disk. Earlier versions stored the text that html2text extracted from
them, sographicle packquoted that text under its own line numbers,
not the file's, and agraphicle fixedit copied from that text could
fail to match the file. Search and project memory read the same stored
text, so they now see a page's markup as well as its words, and a hit or
a quote points at the file's own line.- Office files, spreadsheets, PDF, EPUB and images are converted as
before, and so is HTML that is uploaded or that the Confluence
connector brings in. The GitHub and Google Drive connectors already
kept.htmlfiles as they are. - A folder's HTML file that is not UTF-8, such as a Latin-1 or Shift-JIS
page, or that is larger thanlimits.file_bytes(8 MiB by default), is
still read as its extracted text, as before, up to
limits.document_bytes(128 MiB by default). - An HTML file read as it is counts its whole markup, not just its words,
towardlimits.project_bytes(1 GiB by default), so a folder with many
large pages comes closer to that limit; raise the limit if a sync is
refused. - The notes-first ranking, which is off by default, no longer counts
.htmland.htmfiles as notes.
- Office files, spreadsheets, PDF, EPUB and images are converted as
graphicle review --format githuband the GitHub Action escape&,<
and>in the review's text outside code spans and code blocks, so
markup in a model's comment (an<img>tag, or a<!--that would hide
the rest of the review) shows as text in the posted review and in the job
summary.graphicle pack --format xml: a file whose lines hold</fileor
</section(an HTML page's own</section>, for example) goes inside a
CDATA section, so it no longer closes the pack's<file>or<section>
element. Other files are unchanged, and the element names stay the same.
Graph commands
- A
graphicle graphcommand that reads the graph file, such asqueryor
affected, now says how to build the file when it does not exist yet
(reported by Thomas Thomsen,
#15). Before, it
stopped withgraph file not found: <folder>/.graphicle/graph.jsonand
nothing more. Now, for the default graph file, the next line gives the
command to run in that folder,graphicle-graph extract . --code-only
(the same asgraphicle graph extract . --code-only). The code graph
thatgraphicle setupbuilds is in Graphicle's data folder, for the MCP
server andgraphicle context;graphicle graphreads its own file.
Model profiles
- A model profile with an API key (
key_env) can now use plain HTTP to a
model server on your own network, such as a vLLM host without TLS, when
you list that server's exact host in the new environment variable
GRAPHICLE_PROVIDER_HTTP_KEY_HOSTS(the same format as
GRAPHICLE_PROVIDER_HTTP_HOSTS; a host listed there also counts as
listed in the older variable). The key then crosses the network in clear
text. The variable is unset by default, so such a profile is still
refused until you list its host; Graphicle prints a one-line warning
that names such a host when it accepts one, and connectors and sign-in
still need HTTPS or loopback (asked in discussion #16).
Benchmark kits
bench/swe-bench-pro/measures, without a model, how often a context
holds every file and every line that a fix changes, on 633 tasks of
SWE-bench Pro's public set: the pack, file-level BM25 and the repository
cut to the same budget (e1.py,e1l.py, their reports and
comparisons). It also holds the scripts of the model runs (e2.py,
answers on a sample of the tasks;c4c.py, a billed prompt-cache meter;
live.sh), whose results are not in this release. Results:
results-e1.md
(files, 0.1.9) and
results-e1l.md
(lines, 0.1.9 and the 0.1.10 candidate build).bench/whole-repo/lines.pycounts the changed lines that each context
holds for the whole-repository questions, from each question's pull
request diff placed on its snapshot, and compares two builds question by
question:
[results-lines.md](https://github.com/Graphicle-AI/graphicle/blob/v0.1.10/bench/whole-repo/results-l...
Graphicle 0.1.9
Every crate is at 0.1.9, and graphicle --version prints
graphicle 0.1.9 (core). The Python and TypeScript SDKs are at 0.1.9 too.
Most of what is new was written for Meta's Global AI Developer Hackathon.
HACKATHON.md
says what was written before the event and what during it.
How the new model features were tested
- The new commands that call a model (
ask --pack,plan,fix,
review,pixelandsee) were tested only against stand-ins: local
test servers that answer as the Meta Model API and OpenAI-compatible
servers do, anddemo/mock_meta.py. That covers the prompt cache
requests, the exact counts ofPOST /responses/input_tokens, SAM 3.1 and
computer use. None of them has called the live Meta Model API yet. - The Muse Code plugin was tested with a stand-in for the
museprogram,
not with Muse Code itself. - The GitHub Action of
graphicle reviewwas tested with stand-ins for
curl,graphicleandgh, not on GitHub's runners. - The hosted demo in
demo/was tested againstdemo/mock_meta.py. It is
not deployed.
After upgrading
- Run
graphicle synconce in each project, as after 0.1.8. The saved
graph and the query file are keyed to the program's build, so the first
sync writes both again. Until then a question reads the code graph from
the store, and on a project of 2,000 files or more the prompt hook gives
only the files that define the code names a prompt gives.
Whole-repository packs
graphicle pack [QUESTION]gathers a project's code for one question into
one block of text within a token budget (--budget, default 128,000, up
to 2,000,000): a header, a manifest of what is in and the top files left
out, an architecture summary, the ranked files (small ones whole, large
ones as symbol excerpts with merged line ranges), callers and callees two
steps along call edges, tests, docs and more of the repository. It reads
graphicle context's own ranking and the saved code graph. Formats:
Markdown, XML, or JSON (graphicle.pack.v1, whose chunks' text joined in
order is the pack). Without a question, an overview. See
docs/pack.md.- A pack's ranking is
context's, read deeper (3,000 fused passages), with
two additions: the files of a small folder the question names (by a word,
a path or module segment, or words joined by_) right after the top
files, and the files that define what the top files use (Go identifiers
through their imports, Python modules of the same folder). Up to 256,000
tokens, the ranks past 15 go in as compact excerpts (their passages and
the first lines of the symbols around them) instead of more of the
repository by centrality, and no file takes more than a tenth of the
budget. The manifest lists up to 100 top-ranked files left out. - A pack's ranking reads an issue without its environment sections (a
heading below the title that labels the system information, tested
versions, a<name> version, the environment or the operating system, or
an issue form's question for them) and its<name> version: <value>
lines; a title or a heading that merely names a version stays. - The first pack after an upgrade writes the project's query file for the
new build once, and says so; later packs read it. - The budget is never exceeded: tokens are counted exactly with
--tokenizer tokenizer.json(any Hugging Face tokenizer; the released
program includes the pure-Rusttokenizerslibrary for it), else
estimated from bytes per token by language, calibrated on Muse Spark
Open's counts (7% above them in 22 packs of 128,000 tokens), with a
margin. The same inputs give the same bytes. graphicle pack --layout cachesplits a pack for a provider's prompt
cache. Its repository part comes first and is the same bytes for every
question about a commit at the same budget and settings: a header without
the question, the architecture summary, a map of the folders (files,
tokens and most connected symbols of each), the files with the most
connections in the code graph (whole, or the first line of each symbol) and
the top documentation. The question part follows (a manifest, focus, call
paths and tests) and never repeats lines the repository part holds: it
lists the ranked files already there asin the prefix: path lines a-b,
and gives full excerpts to one ranked file per 8,000 tokens of its room
(each up to two fifths of the room divided among them, or 2,000 tokens
when that is more) and compact excerpts to the ranks after them.
--prefix-share F(default 0.9) is the repository part's share of the
budget at most; 1.0 makes a stable pack, where only the question after it
changes. See
docs/pack.md.- The pack JSON records the
layout,prefix_share(cache layout only),
prefix_tokens,prefix_sha256and apart(prefixorsuffix) on
every section; the prefix sections' text is the start of the pack's text. - The MCP server publishes a
packtool (default 32,000 tokens, at most
200,000) after the tools of 0.1.0's server. Claude Code's essential set
stays five tools;graphicle connect claude-code --tools alladdspack.
Ranking for TypeScript, Java and C++
- The pack's ranking was tuned on TypeScript, Java and C++ repositories
(angular, keycloak and godot) as well as on Go and Python ones
(kubernetes and home-assistant):- it reads an issue without its environment sections, as above, whose
words (graphics drivers, display servers, package versions) pulled
unrelated files up; - files the question names by a code name (
TextEditnames
text_edit.cppandtext_edit.h,FormControlnames
form_control.ts,UserModelnamesUserModel.java), or by two or
three of its words in the languages that name files after their classes
(Java, TypeScript and JavaScript, C and C++), come right after the top
five files: at most 4 files per name, 4 names and 8 files; - TypeScript and JavaScript imports lead to the files that define what the
top files use: relative paths (an ES module's./x.jsisx.ts), index
files andtsconfigpath aliases.
- it reads an issue without its environment sections, as above, whose
- Measured without a model, as the mean share of the files a fix changed
that are inside the pack, whole or as excerpts or outlines of their
symbols (standard layout, tokens counted with the Muse Spark Open
tokenizer), over the 90 questions of three repositories held
out from tuning (pytorch, vscode and elasticsearch, 30 each): 58.1%,
64.3%, 64.6%, 70.9% and 77.9% at budgets of 64K, 128K, 256K, 512K and 1M
tokens, against 55.8%, 63.6%, 61.4%, 68.0% and 76.8% for the pack as it
stood before the hackathon. pytorch gained 2.3 to 10.6 points; vscode
lost 6.6 points at 64K, 0.9 at 256K and 3.3 at 512K. These numbers were
measured before a later change to how a pack reads an issue's
environment sections (the rule above). That change leaves the results of
all 200 development questions unchanged; the held-out questions were not
measured again. The method is that of
docs/benchmarks/whole-repo.md,
whose table is of the earlier pack.
Answers, plans and fixes with Meta's models
graphicle config set model metawrites a Muse Spark profile for the
Meta Model API (https://api.meta.ai/v1, its Responses API, key in
MODEL_API_KEY, modelmuse-spark-1.3,reasoning_effortmedium, sent
asreasoning.effort) and makes it the answer model;
meta:muse-wonder-1.0chooses Muse Wonder. It refuses the-contributor
models, which let Meta train on the data, and areasoning_effortof
none, which the Meta Model API refuses.graphicle config set model compatible:MODEL --url URLdoes the same for any OpenAI-compatible
server, such as Muse Spark Open on vLLM or SGLang. The docs give Meta's
list prices for Muse Spark 1.3 and Muse Wonder (26 October 2026) as
configuration examples; prices stay out of the program.- Model profiles take input limits up to 1,048,576 tokens and output limits
up to 131,072, and an optionalprice(US dollars per million input,
output and cached input tokens).ask --packandplanshow the tokens
in and out from the provider's usage, and a cost only from that price. graphicle ask --packanswers in one model call from a pack that fills
the model's input limit, streams the answer from chat models, checks every
citedpath:lineagainst the working tree and lists the ones that do not
hold. After each call it keeps the provider's prompt tokens over its own
estimate per model profile, and sizes the next pack to fill the input
limit by the provider's count. Thebasicandreflectworkflows are
unchanged.graphicle plan "change request"asks for a plan as JSON (steps, files to
edit with line ranges, new files, tests, risks), checks it against the
working tree and prints it as Markdown or JSON. It changes no files.graphicle ask --pack,graphicle planandgraphicle fixuse the
standard layout by default;--layout cacheand--prefix-sharechoose
the cache layout, which pays off when you ask several questions about
the same commit. A cache-layout request sends the same instructions
first, then the pack, then the question. Without--budget, the
repository part is sized from the model's input limit, not the
calibrated budget, so it stays the same bytes from one question to the
next; when the provider counts more than the estimate, it steps down to
0.8, 0.64, ... of that size, the first whose share fits, and holds within
each step. For the Meta Model API the request carries a
`prompt_cache_ke...
Graphicle 0.1.8
Every crate is at 0.1.8, and graphicle --version prints
graphicle 0.1.8 (core). The Python and TypeScript SDKs are at 0.1.8 too.
After upgrading
- Run
graphicle synconce in each project. Until that sync, a question
reads the code graph from the store, which on a shallow clone of
kubernetes took a median of 22.5 seconds per question (16 cores of a
Linux server, the 22 questions of #8), and on a project of 2,000 files
or more the prompt hook gives only the files that define the code names
a prompt gives.
Questions on large projects
- A question no longer decodes the whole saved code graph (#8). After each
code graph build, a sync also saves a query file beside the saved graph
(gf-cache/<project>/query/<episode>.query).graphicle context, the
prompt hook and the memory server'srecall_projectread it in place
(mapped into memory on macOS and Linux, read whole on Windows) and decode
only what the question needs: every node's text once, to weigh the
question's words, then the postings of its own words, the scoring
strings of the nodes those leave and the records of the code it cites.
A lookup ("Where is X defined?", a bare name, "who calls X") reads the
symbols and references of its names. Packets and the prompt hook's
output are unchanged, byte for byte.- Measured on a shallow clone of kubernetes at
ca8a2a9e4(30,315
files) on a Linux server, against 0.1.7 on the same cores, each call a
new process as the hook runs it. Over the 22 questions of #8 the
mediangraphicle contextcall took 1.34 seconds on 16 cores, against
2.99 seconds with 0.1.7 (90th percentile 1.87 against 3.37 seconds),
and 1.38 seconds on 4 cores, against 3.89 seconds (90th percentile
1.87 against 4.56 seconds). On the 20 of them the prompt hook answers,
it took a median of 1.53 seconds on 16 cores and 1.59 seconds on 4,
against 3.11 and 3.96 seconds. - Over 8 lookups the median
graphicle contextcall took 0.96 seconds
on 16 cores and 0.99 seconds on 4, against 2.52 and 3.44 seconds. - With the data folder and the program dropped from the operating
system's file cache before each call, the median over the 22 questions
was 1.84 seconds on 16 cores and 1.90 seconds on 4, against 3.68 and
4.55 seconds. - The peak memory of a
graphicle contextcall fell from 3.5 GB to 0.6
GB (the median over the 22 questions on 16 cores). - A question read about a third of the query file (a median of 35% of
its pages over the 22 questions, at most 46%); a lookup read a median
of 0.3%. - The query file takes 206 MB of the data folder for that clone, beside
the saved graph's 270 MB (6.45 GB in all, against 6.24 GB). - The main figures of this run, with their labels, are in a table in
docs/benchmarks.md.
- Measured on a shallow clone of kubernetes at
- A sync that builds the code graph also writes the query file: on that
clone a sync after a one-file change took a median of 117.7 seconds,
against 109.5 seconds with 0.1.7, of which saving the graph and the
query file took 28.0 seconds, against 21.0 seconds for the graph alone.
A sync with nothing to do took 2.4 seconds, against 2.5. - Going back to the head set synced just before (a branch switched back
to) finds that head set's saved files: on that clone such a sync took a
median of 17.2 seconds, against 28.6 seconds with 0.1.7, and a question
then took a median of 1.38 seconds over the 22 questions. 0.1.7 kept the
saved graph of the latest episode only, so after such a switch its
questions read the code graph from the store, a median of 22.3 seconds
each, until the next code graph build. - The keys of the saved graph and of the query file now cover the
program's sources and its locked dependencies, not only the engine's, so
a file another build wrote is never read. The first sync after upgrading
writes both again (26.9 seconds on that clone). Until then a question
reads the code graph from the store (a median of 22.5 seconds on 16
cores over the 22 questions), on a project of 2,000 files or more the
prompt hook gives the files that define the code names a prompt gives,
andgraphicle doctorsays so. - A query file that cannot be written for a reason that can pass, such as
a full disk, is tried again by later syncs after a wait (10 minutes,
doubled after each failure in a row, at most 6 hours) and at once by
graphicle sync,graphicle setupandgraphicle doctor --fix. A code
graph the file cannot hold (a node id that is not a string, a value
nested more than 64 levels deep, a section past 4 GiB) is not tried
again until the code graph or the program changes.graphicle doctor
says which, under Questions, and what to do. - A query file, saved graph or file relationships file that is truncated,
malformed or damaged is read around, with the same packet, and written
again. The query file has checksums over its header and each page, and
the saved graph and the file relationships now end with their length
and a checksum: a sync checks the query file's header and the other
files' lengths, and the read that finds damage removes the file, so the
next sync writes it. A file relationships file whose pairs name files
outside its table no longer makesgraphicle contextfail, as it did
in 0.1.7.GRAPHICLE_QUERY_FILE=0makes every question read the saved
graph.
Packaging
server.jsonat the repository's root is the MCP Registry entry of
0.1.7, the latest listed release (it named 0.1.6). A release's entry is
committed after its listing, as
packaging/mcpb/README.md
describes.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.8/install.sh | sh -s -- --version 0.1.8On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.8'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.8/install.ps1 | iexEach archive's SHA-256 sum is in SHA256SUMS and beside it in a .sha256 file.
graphicle.exe and graphicle-graph.exe in the Windows archive carry a signature from a SignPath test certificate. Windows does not trust that certificate, so it treats them as unsigned programs and may warn before it runs them. Code signing policy
Graphicle 0.1.7
Every crate is at 0.1.7, and graphicle --version prints
graphicle 0.1.7 (core). The Python and TypeScript SDKs, at 0.1.0 until
now, are at 0.1.7 too.
Code graph
- The engine follows Graphify 0.9.95 (0.1.6 followed 0.9.91): the four
releases 0.9.92 to 0.9.95 are ported. Against 0.9.95 every comparison check
passes on Linux, and the file ledger marks all 96 application modules
verified
(docs/benchmarks.md).
What changes in the graph:- YAML:
.yamland.ymlfiles are code, read structurally: a node per
key under its file, withcontainsedges, keys nested at most seven
levels deep and 500 keys a file. YAML that holds data rather than
configuration is declined by design and listed as skipped, and unsafe
tags are refused. - C#: each overload of a method is a node of its own (the first keeps its
id, the others get ids salted by their signature), and calls bind by
argument count. Adelegateis a type. - Type aliases and declarations: Python
TypeAlias,type X =and
NewType; Gotype A = B; Rusttypealiases andunionitems; C++
namespace-scopeusing A = B;andtypedef; Kotlintypealias; Dart
typedef; Swiftmacrodeclarations and#macro(...)calls. - Names that differ only by
_,$,#or case keep separate nodes:
JavaScript and TypeScript members, Python module-level classes beside a
function or class of the same id, Go and Rust declarations. - Calls: TypeScript
this.fieldis typed from an assignment in any method;
a JavaScript call on an untyped receiver waits for receiver-typed
resolution; a CommonJSrequirebinding no longer shadows the export it
requires; a pytest fixture parameter is typed from the fixture's return;
Pythonmodule.func()binds the child named exactlyfunc; a bare call
resolved only through a module import staysINFERRED; Solidity
inherited calls,supercalls and modifiers resolve through C3
linearization; a Rustuserooted at a siblingmodreaches its
declaration; an Objective-C member call resolves across a header and an
implementation in different folders; a cross-repository call edge points
at the call site. - SQL: T-SQL names are unbracketed (
dbo.Alpha, not[dbo].[Alpha]),
procedures recordreads_fromandwrites_to,GOends a statement, a
table referenced before itsCREATE TABLEfolds onto it, and a
CREATE TABLEthe grammar cannot parse is recovered. - Each
package.jsondependency entry declares the node its importers
resolve to, labelledname@range. Markdown vault-relative wikilinks
resolve, and a bare method link needs its class cited. Objective-C
NS_CLOSED_ENUMis an enum, and category ids are relative to the
repository. Metal and CUDA qualifiers no longer create nodes without a
source, and a.hwithextern "C"goes to the C++ extractor. - Graph building: string confidences that drifted from the enum are
folded onto it, on nodes as on edges; a node with a source file wins
over a namesake without one; a build without clustering resolves imports
through the old-stem alias index. An incremental build no longer queues
again a file declined by design.
- YAML:
- The AST cache format changed, so the first sync after upgrading re-extracts
every file once. - graph.json keeps parallel edges between two nodes (
multigraph: true).
Every reader of a saved graph.json, not only the MCP server (exportand
merge-driveramong them), reads a file written before (parallel links
undermultigraph: false) the same way, so a result does not depend on
which release wrote the file. - A dependency entry of a JSON manifest such as
package.json, which the
engine now labelsname@rangeand joins to the package it declares, keeps
the stable id of its name (its label up to the first@after the first
character), so a reviewed memory linked to it survives the new label and
later version bumps. Other keys that hold@, such as pnpm overrides or a
jestmoduleNameMapperpattern, keep their whole label. - A code graph episode is named by the engine's graph format as well as the
project's files, so the first sync after upgrading builds the graph again
even when no file changed: C# overloads become nodes of their own and the
nodes the new engine no longer makes are closed. Before, an unchanged
project kept the older engine's graph until one of its files changed. graphicle graph updateworks on a project whose graph is over 512 MiB,
such as kubernetes: before, even its first update failed, reading back its
own temporary graph under the size cap. The engine reads a graph.json over
the cap that it wrote itself (update,watch,serve,query,
explain,path,merge-graphs,cluster-only,label); a larger
graph.json from elsewhere is still refused, andGRAPHICLE_MAX_GRAPH_BYTES,
when set, applies to every file. A graph.json over the cap that an earlier
release wrote has no record of being the engine's own, so updates and hook
rebuilds refuse it until it is rebuilt once, as the error says: run
GRAPHICLE_MAX_GRAPH_BYTES=<N>GB graphicle graph extract --force <project>,
with N above the file's size (add--code-onlywhen no LLM backend is set
up).- The engine extracts YAML structurally (above), so graph.json and the
graphicle graphcommands have its keys, but Graphicle Core does not yet
use those keys for its answers: its code graph leaves out the YAML files
the engine reads as keys (theapm.ymlpackage manifests stay in, as
before), and a YAML path quoted in a memory is taken for data, as a JSON
path is, not for a code file.
Commands, hooks and the language model
GRAPHICLE_BACKENDchooses the LLM provider (noneturns LLM work off);
an auto-detected provider is named before anything is sent.- The semantic extraction prompt now pins each node to the file it came
from; cached semantic results are extracted again once, which costs one
round of LLM calls. - Git hooks: a rebase,
pull --rebase, cherry-pick or revert rebuilds the
graph once; a merge commit rebuilds; a new branch at the same commit does
not; hooks run from the repository's top level. Run
graphicle-graph hook installto add the post-rewrite hook and update the
others. --versionand--helpno longer refresh installed skills, and--help
lists every--platformvalue.queryrefuses a name shared by several nodes (exit 3) and an unknown
--seedexits 4;explain,get_nodeandget_neighborsreport a
substring near miss instead of answering with it.- Merged graphs:
explainandpathkeep same-path files of two repos
apart and name the repo; the tree export draws one root per repo. prsreads CI state from legacy status contexts and keeps a default
branch such asrelease/2.xwhole; a Maven pom contributes only its own
dependencies;serveover streamable-http on an IPv6 address accepts its
[::1]:portHost header.- Detection: only a valid
.gitmarks a repository root; versioned shebangs
such aspython3.12are recognised; an unreadable PDF warns once; images,
audio and video count no words; a.graphiclercsaved with a byte order
mark keeps its first setting.
Connections
- The
graphicleprogram allows plainhttp://to every loopback address
for the services it calls (models, connectors, OAuth, vector and graph
endpoints): the rest of 127.0.0.0/8, such as127.0.0.2, and IPv4-mapped
loopback, such as[::ffff:127.0.0.1], as well aslocalhost,
127.0.0.1and[::1]. Before, a local model or connector on another
loopback address was refused (#11, by @rudycelekli).
SDKs
- The Python SDK keeps the service's
Retry-Afteron an error:
GraphicleError.retry_afteris the delay in seconds (from a number of
seconds or an HTTP date), and the error's text names it, so a caller whose
monthly request budget is spent knows when to try again, as the
TypeScript SDK'sretryAfterSecondsalready says (#10, by @rudycelekli).
ARetry-Afterthat is neither leavesretry_afterasNone, and the
error is still aGraphicleError.
Security
- URLs with credentials, a bad or zero port, or no host are refused;
multicast addresses are blocked; Obsidian tags and Google Workspace
sidecars escape hostile values. - Installing or refreshing a skill (
graphicle graph install) no longer
writes through a symbolic link. A link at the skill'sSKILL.md, or at
the version stamp beside it, is replaced by the new file, and the file it
pointed to is left alone; before, that file was overwritten.
references/is staged in a new private folder with a random name
instead ofreferences.tmp, so a link put there in advance cannot
redirect the copy, and the backups (SKILL.md.bakand the
.graphicle-bakcopies of agent settings) never follow a link. - A symbolic link that a repository commits at
.graphicle/.rebuild.lock,
at the rebuild's temporary graph or at.gitattributesis no longer
followed: before,graphicle graph update, a hook rebuild or
graphicle graph hook installcould truncate, overwrite or add a line to
the file it names.update --no-clusterand the GraphML export replace a
link at their output instead of writing through it. - Credential-shaped text in docstrings and comments is redacted before it
becomes a rationale label.
Dependencies and packaging
- yoke-derive 0.8.4 replaces 0.8.3, which its authors yanked and
cargo denywarned about. Only the lock files and the third-party
licence pages change. server.jsonat the repository's root is again the MCP Registry entry of
the latest listed release (0.1.6; it still named 0.1.2). An entry lists
the SHA-256 of each bundle themcp-registrywo...
Graphicle 0.1.6
Every crate is at 0.1.6, and graphicle --version prints
graphicle 0.1.6 (core).
SDKs
- The Python and TypeScript SDKs allow plain
http://to every loopback
address: the rest of 127.0.0.0/8, such as127.0.0.2, and IPv4-mapped
loopback, such as[::ffff:127.0.0.1], as well as127.0.0.1,[::1]
andlocalhost. Before, a local service on another loopback address
neededinsecure_http=True(Python) orinsecureHttp: true
(TypeScript) (#9, by @rudycelekli). The Python SDK reads an IPv4-mapped
address by its IPv4 address on every Python version, and its requests
to all of these addresses ignore proxy settings, as they did for
127.0.0.1.
Security
- tokio 1.53.3 and ctutils 0.4.4, for RUSTSEC-2026-0386 (the safe
constructors of tokio'sAsyncFdbreak I/O safety; Graphicle does not
call them) and RUSTSEC-2026-0385 (ctutils made masks andu128
comparisons that were not constant-time). Only the lock files and the
third-party licence pages change. - The Python environment of the engine's comparison suite pins pypdf
6.21.2, which fixes security advisories.
Documentation
docs/benchmarks.mdhas a section of
independent measurements.
Its first entry is the rerun by @selimaytac, who reported #8, of their
22 questions about kubernetes on an Apple M3 Pro, with no answer model:
graphicle contexttook a median of 153.5 s per question on 0.1.3 and
9.5 s on 0.1.5, and the prompt hook returned a packet for 18 of 22.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.6/install.sh | sh -s -- --version 0.1.6On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.6'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.6/install.ps1 | iexEach archive's SHA-256 sum is in SHA256SUMS and beside it in a .sha256 file.
graphicle.exe and graphicle-graph.exe in the Windows archive carry a signature from a SignPath test certificate. Windows does not trust that certificate, so it treats them as unsigned programs and may warn before it runs them. Code signing policy
Graphicle 0.1.5
Every crate is at 0.1.5, and graphicle --version prints
graphicle 0.1.5 (core).
Questions on large projects
- Each sync keeps a passage index of the project's files in the store, and
graphicle context, the memory server'srecall_projectand the prompt
hook look a question up in it instead of reading and scoring every file of
the project (#8, reported by @selimaytac). A sync reads only the files
that changed since the last one. After each code graph build, Graphicle
also saves the graph and its search index in the data folder
(gf-cache/<project>/query/), so a question reads them instead of
rebuilding them from the store.- Over the 22 kubernetes questions of #8, on a shallow clone of
kubernetes (30,315 files) on 16 cores of a Linux server, a question to
graphicle contexttook a median of 3.1 seconds, against 27.9 seconds
with 0.1.4. On duckdb (14,309 files) the median over 10 questions was
2.6 seconds, against 20.9 seconds. - A question ranks every passage of the project, as the full path does
within its bounds. A project past those bounds (50,000 documents or
40,000 passages) was ranked on the documents that matched the question
best, and is now ranked whole. - The index takes room in the store and time at a first sync: on that
kubernetes clone the data folder held 6.22 GB after a first sync,
against 5.80 GB with 0.1.4, and the sync took 239.5 seconds, against
235.4 seconds. On duckdb a first sync took 125.9 seconds, against 112.4
seconds. Later syncs read only the files that changed; a sync merges
the index when the files that changed since it was built hold more than
30% of its passages, andstorage.prunemerges it too, so the entries
of files that went away go. - A store from an earlier version builds its index at its next sync, and
its questions take the full path until then. Calls with options the
index does not serve, such asinclude, and projects with reviewed
memory also take the full path;docs/configuration.mdlists them. The
packet says what it read inpassage_index.
GRAPHICLE_PASSAGE_INDEX=0makes every question take the full path,
andGRAPHICLE_SAVED_GRAPH=0makes it read the code graph from the
store.
- Over the 22 kubernetes questions of #8, on a shallow clone of
Prompt hook
- The hook's time budget is a setting:
graphicle config set prompt_context.seconds N(1 to 25 seconds, 10 by default) or the
GRAPHICLE_PROMPT_CONTEXT_SECONDSvariable. The hook's own timeout is 30
seconds. - While the passage index of a project of 2,000 files or more is not
ready, the hook gives the files that define the code names a prompt
gives, from the code graph, without reading the project's other files. A
smaller project, and a project with reviewed memory (whose memories only
the full read gives), are asked in full, as before. - When the hook gives up for time, or answers that way, Claude Code shows
one note a session that says so and what to run. For a project with
reviewed memory, the note says that a sync does not make it faster. - Graphicle 0.1.4 and earlier refuse a configuration that sets
prompt_context, a field they do not know. After setting it, do not run
an older Graphicle on the same data folder, such as an MCP server started
before the upgrade. - A prompt that asks where code is in plain words, such as "Which file and
functions compute this?" or "Where is that latency recorded?", is read as
a code question. - Over the same 22 kubernetes questions, the hook gave a packet within its
10-second budget for 20 of them, and read the other 2 as questions in
plain words. With 0.1.4 it gave none: it ran out of time on 11 and did
not read the other 11 as code questions.
Setup and doctor
graphicle doctorhas a Questions check: whether the project's passage
index is built and current and its code graph saved, or what makes its
questions slow (a missing or stale index, reviewed memory), with the
command that fixes it.graphicle setupsays the same in itsquestions
field and line. A project of fewer than 2,000 files is only described.
Packets
- A packet tells its reader to read on with what the reader has:
read_project_sourceover MCP, and fromgraphicle contextand the
prompt hook, the line of the file to continue at. It no longer names
read_repository_fileorread_project_evidence, which no tool set has.
Sync
- On a file system that ignores case (the default on macOS and Windows), a
tracked file that an ignore pattern matches only in another case, such as
src/Foo.jsagainstfoo.js, was read twice, and its bytes counted
twice. It is read once. Two hard links to one file are still read as two
files.
Extension interface
- When an installed extension sets the most tokens a read's result may
hold, acontextresult over it is packed again with a smaller budget
until it fits (at most 4 rounds, down to 256 tokens, reported in
response_sized), instead of refused with 413. Other reads are still
refused.
Windows
graphicle.exeandgraphicle-graph.exeare signed through SignPath with
a test certificate, which Windows does not trust, so Windows still treats
them as unsigned programs. When the signing fails, the release ships them
unsigned; the release notes say which.graphicle.exeandgraphicle-graph.execarry version information
(product name, company, description and version), which Windows shows in
each file's properties.
Other changes
- The install scripts and the Homebrew formula say that Graphicle checks for
a newer release at most once a day by default, and how to turn that off. - The code signing policy,
docs/code-signing.md, lists every case in which
Graphicle contacts the network, what each one sends and how to turn it off
or avoid it. - The release workflow's signing and Homebrew tap jobs run in GitHub
environments that only version tags reach and a maintainer approves, and
only those jobs can read their tokens.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.5/install.sh | sh -s -- --version 0.1.5On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.5'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.5/install.ps1 | iexEach archive's SHA-256 sum is in SHA256SUMS and beside it in a .sha256 file.
graphicle.exe and graphicle-graph.exe in the Windows archive carry a signature from a SignPath test certificate. Windows does not trust that certificate, so it treats them as unsigned programs and may warn before it runs them. Code signing policy
Graphicle 0.1.4
Every crate is at 0.1.4, and graphicle --version prints
graphicle 0.1.4 (core).
Connections
- HTTPS connections trust the certificate authorities of the operating
system as well as the roots bundled with Graphicle: the Windows
certificate store, the macOS keychains and the system bundle on Linux. A
model provider whose certificate comes from a company's own certificate
authority is now reached once that authority is in the system trust
store, as curl and browsers reach it. Before, only the bundled roots were
trusted, so such a provider could not be reached (#7, reported by
@Mohammed-Tabiza). WhenSSL_CERT_FILEorSSL_CERT_DIRis set, its
certificates are read instead of the system's. If the system's
certificates cannot be used, Graphicle still connects with the bundled
roots. - A failed connection to a model provider now gives its cause, for example
invalid peer certificate: UnknownIssuer. When the server's certificate
is refused, the error also says what to do: install the certificate
authority in the system trust store, or setSSL_CERT_FILEto a PEM file
that holds it.graphicle askreports that the provider's certificate is
not trusted, instead of suggesting a network or proxy problem. The graph
engine's model, pull request triage and URL fetch requests give the same
causes and hint.
Other changes
- The Python environments of the engine's comparison suite pin Pillow
13.0.0 and certifi 2026.10.19, which fix security advisories.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.4/install.sh | sh -s -- --version 0.1.4On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.4'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.4/install.ps1 | iexEach archive's SHA-256 sum is in SHA256SUMS and beside it in a .sha256 file.