Repository navigation
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_keybuilt from the project, its commit and the pack's
prefix hash (never from the question) and, on the Responses API, a
24-hourprompt_cache_retention; other profiles opt in with
"prompt_cache": true.- Every request is fitted to the input limit: its estimate, times the
profile's calibration, must fit, and a request near the limit is counted
exactly withPOST /responses/input_tokensfor the Meta Model API; the
pack is made again smaller while it would not fit. A profile'stokenizer
(atokenizer.json, such as Muse Spark Open's) makes these packs count
exactly without the API. graphicle fix "issue"(or--issue-file) makes a pack and a plan. The
pack is in the standard layout by default, since one run asks about one
issue and a shared repository part would only take room from the files
the issue needs;--layout cacheor--prefix-sharekeeps the cache
layout. It asks for the edits as search-and-replace blocks and new files,
checks each round's edits as a whole (paths, search texts, and new files
against each other and the folders on disk) and applies them all or none,
putting back every file of the round if a write fails, on a new branch in
a new git worktree from HEAD, made once the plan has come back. It runs
--test CMD(or the configuration'sfix.test) there with a timeout
(--timeout, 1 to 86,400 seconds), and sends a failure's output and the
diff back for at most--roundsrounds (default 3), each request fitted to
the input limit. It reports the branch, worktree, files changed, each
round's result, tokens and cost, and the cited lines;--commitcommits
on the new branch.--focus PATH[:LINE|:START-END](up to 50) puts
passages first in the pack's ranking, whatever the issue's words rank:
PATH alone is the whole file, PATH:LINE the 40 lines on each side. Edits
outside the repository (absolute paths,.., any spelling of.git,
symlinks leading out or into.git) are refused; git runs with hooks off
and without variables that point it elsewhere or add configuration (your
configuration files, and so your commit identity, are kept); the test
command never comes from the model and runs without the model key
variables of every profile, those stored in the workspace too, whose
values are hidden in its output; on Linux, Graphicle makes itself not
dumpable before the test starts, so the test cannot read Graphicle's
environment through/proc. The test still runs as you and can read what
you can: use a container or virtual machine for repositories you do not
trust. Nothing is pushed. See
docs/fix.md.- The spend log: every model call of
ask --pack,plan,fix,review,
pixelandseeadds one line tousage.jsonlin the data folder
(tokens in, cached, out and reasoning, seconds, the cost at the profile's
configured price, status; never the prompt or the answer).graphicle usageadds it up by day and model, with the cached share;--sinceand
--json. After each answer, one line gives the tokens in (cached, with
their share), out, and the cost. - Cost caps in a profile, in US dollars at its configured price:
max_cost_per_callrefuses a call whose worst case (the whole input
uncached, by the provider's count or the calibrated estimate plus 10%, and
the output limit) costs more, andmax_cost_per_dayrefuses a call whose
worst case would take the day's cost of the profile past it. Calls not
logged yet count at their worst case (held inusage-pending.json), so
calls at the same time count against each other; calls without reported
usage count at their worst case; a spend log that cannot be read refuses
capped calls. Each refusal names the setting. A held worst case counts
whatever its day (a call running past midnight UTC counts in the new
day) and ends when its call is logged, its process ends, or after 40
minutes.graphicle usagelists the calls not logged yet and the log
lines it skipped;--clear-pendingremoves the held worst cases.
Review a change: graphicle review and its GitHub Action
graphicle reviewasks a long-context model (Muse Spark by default, with
themetaprofile) to review what a branch adds since its merge base with
the base branch, as a pull request shows it. One model call gets a
cache-layout pack whose ranking puts the changed hunks first, so it holds
the changed code, the callers and callees of the changed symbols and
their tests, then the architecture lines of the modules the change
touches, the changed hunks and the diff. The model returns comments with
a severity andpath:lineevidence. A comment is kept only on a changed
line of the head with at least one citation that holds in the working
tree; it is flagged when no citation holds, and dropped when it is on
another file, outside the changed hunks, empty, a repeat or past
--max-comments(20 by default). Formats:markdown,json, and
github, the body of GitHub's create-a-review call, always aCOMMENT
that never approves or requests changes. It changes no files and posts
nothing. See
docs/review.md.- A composite GitHub Action in
packaging/github-action/runsgraphicle review --format githubon a pull request and posts one review. It
installs a Graphicle release pinned by version and SHA-256, runs on the
pull_requestevent only (it skips pull requests from forks, which get no
secrets, and refusespull_request_target), gives the model key only to
the review step and the GitHub token only to the posting step, and refuses
a call whose worst case costs more thanmax-cost-usd(0.50 US dollars by
default, at Muse Spark 1.3's list price of 26 October 2026). 0.1.9 is the
first release it can install. See
the GitHub Action.
From the screen to the code: see, pixel and the flow
graphicle pixel SCREENSHOT --at X,Yfinds the code that draws the
element at a point of a screenshot. SAM 3.1 (sam-3.1on the Meta Model
API) finds the element's box, a vision model (Muse Spark by default) reads
its strings, and Graphicle searches the project for them as string
literals (exact, then with mnemonics, ellipses and case set aside, then
with placeholders), follows the keys ofpackage.nls.jsonand of English
JSON locale files to where they are used, adds the code graph's
symbols named like the element, and ranks the candidates aspath:line.
--textgives the strings and makes no model call;--explainasks the
model to rank the top candidates again from a small pack and explain
them. SAM's calls are priced per image (price.per_image).graphicle seelets a model drive a web app in a browser you run, with
computer use on the Meta Model API (Muse Wonder or Muse Spark 1.3), until
the bug an issue describes shows (or, with--look-for expected, the
expected behaviour). A driver command of yours runs the model's clicks and
keys and returns screenshots;demo/browser_driver.pyis one, headless
Chromium that loads only the app's origin, blocks service workers and
closes WebSockets to other origins. Each request replays the run so far,
the model's encrypted reasoning included. It keeps every screenshot and a
step log, and ends with a point on the last screenshot forgraphicle pixel. A run takes at most 29 model calls (--steps, 25 by default). A
pending safety check stops the run unless--acknowledge-safety-checks
is given, and each acknowledgement is logged; the driver gets no model
key; each call is checked against the profile's caps and the run's
--max-cost(3 US dollars by default), and a profile without a price is
refused. See
docs/flow.md.demo/flow/flow.pytakes one bug from the screen to a tested fix as one
command:seereproduces it,pixelfinds the code,fix --focus
patches it on a new branch and runs the app's tests, andsee --look-for expectedchecks the patched app. It writes a receipt with the steps,
citations, diff, the end of the test log, the screenshots before and
after, and each call's tokens and cost. One budget holds for the whole
run (--max-run-cost, 3 US dollars by default). It has run end to end
only againstdemo/mock_meta.py, on a small app of ours and on
excalidraw issue 12053, not yet against Meta's live API.demo/also holds a small web app for trying Graphicle with Meta's models
on kubernetes, pytorch and vscode: a question answered from a cache-aware
pack, and a click on a VS Code screenshot answered bygraphicle pixel.
It runs thegraphicleprogram with fixed arguments and never exposes
Graphicle's own local server. See
demo/README.md.
Muse Code
graphicle setupconnects Muse Code: it finds it by its settings folder,
~/.config/muse, or themuseprogram, and adds Graphicle's MCP server
to themcp_serversof~/.config/muse/settings.json, with
"mode": "optional".graphicle disconnect museremoves it. See
docs/muse-code.md.- A Muse Code plugin, as a preview: the MCP server, a skill and hooks in one
package. With themuseprogram on yourPATH(or in~/.local/bin),
graphicle connect muse --hookswrites it into Graphicle's data folder,
installs it withmuse plugins install --scope user(or updates it) and
removes the settings entry it replaces; approve it once withmuse plugins approve graphicle. Setup does not install it: the plugin was
tested against a stand-inmuseprogram only, and stays opt-in until a
check with Muse Code itself has passed. Rungraphicle disconnect muse
before you uninstall Graphicle or delete its data folder: it is not
confirmed that Muse Code skips a plugin's server that fails to start. - The plugin's hooks are built to add context without a tool call: at the
start of a session, the project's map (the repository part of a
cache-layout pack) and its reviewed memories; for a code question, the
cited excerptsgraphicle contextfinds (at most 8,400 characters);
after a batch of tool calls that searched the files, one sentence on
Graphicle's graph tools (at most five times a session). They keep the
start of each request the same bytes through a session, so that the
prompt cache can keep serving it; which hook events reach the model in
Muse Code itself is not yet observed. The hooks never block Muse Code:
each exits 0, and the session start waits at most 2.5 seconds for its
context. - Session memory with the plugin: the
Stop,PreCompactandSessionEnd
hooks hand Muse Code's session log tographicle sessions import, so
finished turns become sources of the project, and a decision one session
records withpropose_memoryreaches the next session's start once a
person approves it. graphicle mcp --or-workspace, the plugin's server, starts in any folder:
it serves the project of that folder, else every project of the
workspace.
Fixes
graphicle setupno longer stops when it cannot write a Git hook, as in
Claude Code's sandbox, which does not let it write.git/hooks,
.mcp.jsonor.claude/settings.local.json(reported by Thomas Thomsen,
#15). Before, it
stopped with "Local I/O failed: Operation not permitted (os error 1)"
without naming the file, and printed no summary, so the line to add to
.mcp.jsonby hand was lost too. Now each hook it cannot write is listed
with the reason, the summary gives the line to add to the hooks by hand,
and setup goes on with its other steps.AGENTS.md,CLAUDE.mdand the
Graphify entries that setup removes are handled the same way, and an
agent's settings file that cannot be backed up still gets the entry to
paste into it. A hooks file that setup cannot write, Claude Code's
.claude/settings.local.jsonor Codex's~/.codex/hooks.json, no longer
fails the agent's connection. The agent stays connected,.mcp.jsonis
listed with the files setup changed, and the hooks are listed as skipped
with the file and the reason. The summary gives thegraphicle connect
command that adds them later from a normal terminal. Run by hand,
graphicle connect --hooksstill stops on such a file, and now names it.
In a repository whose whole.gitfolder is read-only, as in Codex's
default sandbox, setup also finishes: it leaves.git/info/excludeas it
is, and the summary gives the lines to add to it to keep setup's backups
and the settings file it created out ofgit status. When Codex's
config.tomlor Graphicle's data folder cannot be written, the error
names it.- An issue whose title names a version (a level-1 heading such as "...
Version Check Preferences") lost every section under its title to the
environment-section rule, so the question came out empty andgraphicle packrefused it. A title or a heading that merely names a version now
stays, and a question that still comes out empty is ranked as written.
This was found before the release, in 18 of 633 issues of a public
software engineering benchmark. - Dependencies: zstd 0.14.3, zstd-safe 8.2.0 and zstd-sys 2.1.2, for
RUSTSEC-2026-0391, -0398, -0403 and -0410. zstd 0.13.3 and zstd-safe 7.3.0
stay: only jieba-rs 0.11.0 brings them in, through include-flate 0.3.4, to
unpack its built-in dictionaries, a path that does not reach the affected
functions, and eachdeny.tomlsays so for those three advisories. graphicle config set model ollamareadsOLLAMA_HOSTwhen its scheme
is not lowercase (HTTP://gpu.lan:11434); it saved
http://127.0.0.1:11434instead (#12, by @rudycelekli).graphicle serve --port 80accepts theHostheader that browsers and
curl send without the default port (127.0.0.1orlocalhost); it
refused every such request as an unexpected host (#13, by @rudycelekli).- A memory library test failed now and then on macOS when tests ran in
parallel: two tests could make scratch folders of the same name, since
macOS clocks tick in microseconds. A per-process counter keeps them apart.
Docs
- New pages:
Packs,
Fix,
Review,
See it, find it, fix it, check it,
Muse Code,
and
the whole-repository benchmark:
its questions, arms and scorer, fixed before any model run; the context
recall of the pack without a model (a file counts when the pack holds any
of its text); and the cost of a question with the
prompt cache, computed at list prices and not billed. Its model runs have
not been made yet. docs/configuration.mdcovers Muse Spark, prices, the spend log and the
caps;docs/agents.mdcovers Muse Code, and Claude Code and Codex on
Meta's models;docs/mcp.mdcovers thepacktool.- The README gives "Agent memory, compared" near the top, a still of
0.1.8'sgraphicle setupas its hero, the 0.1.8 chart of time per
question on kubernetes, and the new commands, anddocs/benchmarks.md
gives the early pre-release memory runs on GPT models. - The benchmark kits are in the repository:
bench/whole-repo(the
whole-repository benchmark),bench/pixel(pixel to code) and
bench/muse-code(Muse Code with and without the plugin, and the
two-session memory demo).
Packaging
server.jsonat the repository's root is the MCP Registry entry of
0.1.8, the latest listed release (it named 0.1.7). A release's entry is
committed after its listing, as
packaging/mcpb/README.md
describes.packaging/muse-code-plugin/holds the Muse Code plugin asgraphicle connect muse --hookswrites it, andpackaging/github-action/the
GitHub Action ofgraphicle review, whose scripts CI tests with
stand-ins.
Install
brew install graphicle-ai/tap/graphicle
# or
curl -fsSL https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.9/install.sh | sh -s -- --version 0.1.9On Windows (x86-64, preview), in PowerShell:
$env:GRAPHICLE_VERSION = '0.1.9'; irm https://github.com/Graphicle-AI/graphicle/releases/download/v0.1.9/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