Repository navigation
Releases: maci0/clanker
Release list
v0.11.1
Security
- Web UI: the vendored Preact is upgraded from 10.27.2 to 10.27.3, which
fixes a JSON VNode injection (GHSA-36hm-qxxp-pg3m, high).ui/vendor/README.md
now records exact upstream versions for Preact, htm and signals-core, which
is how the affected release was identified.
Fixed
-
The SBOM describes each vendored web module that is also an npm dependency
as one component, carrying its vendored path and digest, instead of two
entries with the samebom-ref. -
Web UI: the page no longer scrolls behind the app shell when a view jumps
to a section (screen-reader status lines stretched the document); the theme
button shows the theme name instead of a clippedtheme: …; the music dock
sits under the phone navigation drawer instead of over it; an empty System
progress log no longer draws an empty box; hints and empty states use the
body font with no letter-spacing. -
Brand guide contrast table now measures the sidebar's text and
current-page marker;DESIGN.mdand the brand guide describe the shipped
sidebar-and-cards layout.
v0.11.0
Added
- WCAG AA contrast for every palette the web UI ships: the day and night
cabinet intailwind.src.cssand every named theme inthemes/. Includes
a contrast regression test suite (ui/app/contrast.test.ts) and a
standalone browser icon directory atdocs/brand/icons.html. - Web UI rail iconography and Headlamp layout styling: every destination in the
rail wears an icon from theicons.jsgrid, paired with aligned typography and
brand icon assets indocs/brand/icons/. - Tool call latency tracking in the
/api/metricssnapshot, with cumulative
latency buckets (le_100,le_1000,le_10000).
Fixed
- A2A delegation deduplication: retried delegations deduplicate on their
JSON-RPC id, evicted response bodies are properly freed without memory leaks,
and entry counts are bounded atmax_entries. - Child process lifecycle: bound process termination with SIGKILL escalation
to prevent hangs on wedged children. - Mesh replication: close mesh join leaks, propagate session erasure across
mesh session replicas, and prevent socket double-close descriptor races on leave. - Job execution: bound second-waiter spins and exec-child exit hangs.
- Web UI: respect reduced motion preferences, trap Tab navigation inside
dialogs, and allow the navigation rail to scroll before the conversation list
collapses. - Preset safety: refuse unloadable presets rather than silently running turns
unfiltered. - Guest prompt safety: fence untrusted tool results and observation text in
guest prompts. - E2E testing: make the mock LLM test harness deterministically replayable with
kernel-assigned ephemeral ports and fixed seed. - Linting: deduplicate
required-versioninruff.toml.
Changed
- Web UI asset weight budget now accounts for absolute-specifier imports.
- Pre-commit hook runs
bun install --frozen-lockfilebefore JavaScript
linting to avoid skipping linter in fresh checkouts, and ratchets findings
deterministically across environments.
v0.9.0
Changed
- Version bump only. No consumer-visible changes since 0.8.0.
v0.8.0
Fixed
- On a narrow window the masthead actions wrap onto their own row, and the
instance, peers, session, and help controls hide, so Jump and the theme
label stay inside their buttons. clanker updateon macOS asks for the published asset
clanker-<tag>-aarch64-macosorx86_64-macos. The abi tagnoneis
not part of that name. Linux assets still includemusl.- The Music plugin assigns its player before registering the view, so the
page-load boot can callensureinstead of toasting that it failed to
start.
v0.7.0
Added
clanker updatereplaces this binary with the latest verified GitHub
release after the asset matches its.sha256sidecar.--checkreports
the release and does not download or replace.--repo owner/nameselects
the repository (defaultmaci0/clanker). A failed verification leaves the
binary in place.
Fixed
- Icon controls in the web shell show their glyph instead of an empty
labeled button. New chat uses the primary actuator. The rail drawer uses
the cabinet elevation token. Labels in the masthead, rail, and composer
stay inside their controls, and those regions do not widen the page. - The web UI stylesheet is served as CSS. It was sent as JavaScript, so
the browser refused to apply it.
v0.6.2
Fixed
clanker --helpandclanker --versionalready say the output ran out of
space when stdout cannot accept another byte. The release journey now
expects that hint.--dump-configstill namesNoSpaceLeft.
v0.5.0
Compatibility-breaking minor: symlink and Origin/Host hardening, plus numeric
config and SBOM field corrections. Migrations are under Breaking, Security,
and Fixed.
Breaking
- Security hardening changes compatibility for symlinked web UI assets and
browser requests with mismatched Origin and Host. See Security below for
the previous behavior and required upgrade steps. - Numeric config validation now rejects previously accepted fractional integer
settings and non-finite numbers. SBOM consumers using the old
relationshipsfield or base64 hashes must adapt to the corrected fields.
See Fixed below for migrations for both changes.
Security
- Disk-backed web UI plugin assets, themes, and command catalogs no longer
follow symlinks in files or parent directories. Previously those links could
serve files outside the asset directory. Upgrade action: replace linked
assets and linked directories with regular files and directories in their
expected locations; refused assets return 404, and a linkedthemes/
directory produces an empty theme catalog. - Browser requests carrying
Originnow require its authority to match the
request'sHost(case-insensitively), not merely another allowed address.
For example, an Origin ofhttp://localhost:4173with Host
127.0.0.1:4173is now refused. Upgrade action: use the same hostname and
port for the page and its API requests; reverse proxies must preserve the
browser-facing Host and keep that hostname in the configured host allowlist.
Requests without Origin retain their existing behavior. - The
scheduleguest's filesystem grant isstate/schedule.jsonand
state/schedule/log.jsonl, not thestate/schedule/directory. Other files
under that directory are no longer reachable from the guest. No migration if
the tool only used those two paths. - The
skillsguest no longer inherits[agent] tools_dirprefixes. It still
readsskills/,state/skills.json, and[agent] skills_dir. Tools that
need the tool directories keep their own grant.
Changed
- Successful
/api/*responses log at debug, with request id, method, path,
status, and duration. Info-level serve output is unchanged.
Fixed
[improve] backlog = falsenow disables backlog seeding as documented.
Previously the loader ignored the setting and kept the defaulttrue.
Existing boolean settings need no migration; string values such as
backlog = "false"must becomebacklog = false.- Numeric configuration is validated instead of misparsed: a fractional
integer setting (request_timeout_ms = 0.5) is refused rather than
truncated to0, andnan,inf, and overflowing float literals
(1e9999) are refused where a number was expected. A config that loaded
before with one of these values now fails at startup with a diagnostic
naming the setting and a corrected example. Upgrade action: replace
request_timeout_ms = 10.9withrequest_timeout_ms = 10to preserve its
former truncated value, or choose the intended whole-millisecond deadline.
Integral floats such as60.0remain accepted. Replace non-finite values
with a finite value valid for the setting, or remove the override to use its
default; see Configuration errors. - Session replication reports the last committed cursor after rolling back a
batch containing a sequence gap. Retrying from that cursor now includes the
rolled-back events instead of skipping them. - Knowledge search decodes URL-encoded queries and collection filters before
forwarding them to the tool, so spaces, Unicode, and escaped punctuation
search for the intended text. The web UI also discards stale search replies
after the query changes. - The generated SBOM (
scripts/sbom.py, attached to GitHub releases as
sbom.cdx.json) corrects its CycloneDX hash and dependency fields: hash
entries carry algorithm names such asSHA-256instead ofsha256, with
hex digests instead of base64, and the component graph is published under
dependenciesrather than the unrecognizedrelationshipskey. Consumers
of the old fields must readdependencies, decodehashes[].contentas hex,
and accept the hyphenated uppercase algorithm names. - The web UI configuration editor keeps edits made during an in-flight save
marked unsaved, rather than treating text that was never submitted as saved. goal_updaterejectstask_addwith an empty id or an id already present
on that goal, instead of appending an unaddressable or duplicate task.
Omittask_add.idto generate an id, or supply a non-empty id unique within
the goal. Existing tasks are left unchanged when an add is refused.- A goal-loop evaluator verdict without a usable
reasonno longer ends
the loop: it is treated ascontinueand the loop keeps working. Only
verdicts naming why they finished are accepted asachieved/blocked. - An invalid
chat subscribe <room> <value>is a usage error (exit 2) that
changes nothing, instead of silently turning the subscription off. The
accepted spellings areon/true/1/yesandoff/false/0/no.
Replace any other value previously used to unsubscribe withoff; omitting
the value still subscribes. - Command and flag help, and
--dump-config, now exit 1 when stdout cannot
be written instead of reporting success after losing the requested output.
A broken pipe still exits 0, preserving early-closing pipeline behavior. - Workspace names, root names, and resolved root paths that are not valid
UTF-8 are refused and leavestate/workspaces.jsonunchanged. - A failed or timed-out web UI vendor script load no longer sticks, so a
retry can fetch the file again. - Refreshing the system prompt no longer keeps temporary per-turn guidance
from the previous turn. - Rate-limit windows expire at the 60-second boundary instead of one second
later. - Goal-loop evaluator evidence is escaped and length-bounded before it is
interpolated into the evaluator prompt. - A time-seeded sandbox run records a replayable
agent.seedvalue, and
setting that seed reproduces the guest RNG stream. - The TUI model picker says "no usable models" when none are configured, and
points atclanker doctor, instead of treating that the same as a filter
miss.
v0.4.0
Developer tooling only: no public surface changes.
Changed
- The zig grammar build (
tools/grammars/build.sh) now fetches the
tree-sitter-zig master tip that understands Zig 0.17 and applies
tools/grammars/0001-zig-0.17-dev-support.patchbefore generating, so the
built grammar matches the language this checkout targets instead of the
tag that predates it. The cached clone is reset and cleaned first so a
patch cannot stack on a dirty tree, and the tree-sitter CLI is required:
once a patch touchesgrammar.js, regeneration is not optional. - Development dependency
oxlint1.79.0 to 1.80.0, withbun.lock
refreshed to match, since CI lints underbun install --frozen-lockfile.
v0.3.0
Added
themes/win2k.json, the Windows 2000 "Windows Standard" scheme as a web
theme: ButtonFace grey panels, a white window well, the navy title-bar blue
as the interactive accent, and the 1px hard-edged ButtonHilight/ButtonShadow
bevels the system drew instead of soft shadows.themes/win2k.css, that theme's chrome, which tokens cannot express: win2k's
own pixel cursors, the caption gradient on the masthead and dialog headers,
pushed-button faces with the default button's black ring, sunken text wells
and checkboxes, 16px arrow scrollbars, menu and dialog frames, and flat LED
blocks where the cabinet drew glowing lamp domes. The page links it the first
time the win2k theme is applied and never for another theme, read from the
catalog'scssname;GET /webui/themes/<name>.cssserves a palette's
companion sheet fromthemes/the way the palettes themselves are served, so
a themed skin stays a drop-in with no host rebuild and no page weight.
Changed
- Skill triggers:
lookup(wasresearch) no longer steals theresearch
tool;improveno longer fires on ordinary code edits;write-goal,
mcp, andponytaildescriptions name the phrases that should load them.
clanker gateskills-inventory now fails a frontmatter description longer
than the 220-byte prompt clip, instead of listing a truncated trigger. GET /api/sessions/searchandclanker session searchgo through the
sessionsguest, so the Search page, the CLI, and thesession_search
tool share one hit shape (id,title,updated,archived,turn,
role,snippet,more,truncated). The guest used to dropturn
andarchived, which is what the Search page jumps on.clanker chat --helpnames the subcommands (rooms,send,history,
subscribe) on the usage line. Barechatis stillchat rooms.clanker config --helpnamesdumpon the usage line. Bareconfigis
still a dump.- Web UI PatternFly radius and glass tokens follow the cabinet 2–4px plate
scale instead of PatternFly's 16px/24px cards and blur. Engraved labels
share--track-label; titles are untracked.
Fixed
gh_readcaches GitHub responses under(url, token), not the URL
alone, so a rotatedGITHUB_TOKENis not served another identity's
body. Expired files instate/gh_cache/are deleted on the next write.GET /api/catalogno longer holds the catalog lock across a models.dev
fetch, and the in-process snapshot is dropped when
state/models-dev.jsonchanges, so aclanker providers refreshfrom
another process is visible without a restart.clanker mcprecompiles a cached tool when its.wasmfile changes,
matching the agent loop.- Creating a board card that names a goal already mirrored by a live card
returns that card instead of posting a second add. A retried HTTP POST or
two browsers mirroring the same goal used to leave two cards; the fold
now keeps the first. clanker notify(and the peers notify tool) stamps a delivery id that is
stable for a given message within a 60-second window, so a retry after a
lost response is dropped by the inbox instead of stored twice. Passid
to pin a longer-lived key.note_writeof a sentence already instate/learnings.mdreturns
duplicateand does not append a second bullet.- Trimming
state/autolearn.jsonl,state/reasoning.jsonl, and
state/token_stats.jsonlreads a bounded tail instead of the whole file.
A log that had grown past its cap used to allocate without bound (autolearn
with an unlimited read) and then fail to trim, so the file kept growing. - Session search no longer opens every conversation database when the FTS
index already named the matching ids. - Parallel tool workers now receive the same agent sandbox extras as the
sequential path, including the conversationsession_id. A parallel
kernel, debug, or jobs call used to land under"default"instead of the
run's session. clanker run --streamwas documented and parsed, then refused as not an
option for the command, so a monitor could not get the live usage lines
the flag exists to print.clanker chat send <room>with no message saidclanker notifyneeded
one. The two commands shared the same missing-argument token.- Session databases, their WAL sidecars, and the session full-text index are
created owner-only (0600). sqlite3's default create mode left conversation
text world-readable on a shared machine. - Trimming
state/reasoning.jsonlkeeps the owner-only mode; the rewrite
used to drop it to the process umask. - A failed scheduled entry logs the task's length, not the task text.
- Process-global DAP session and background-job tables are released at
exit, so a debug-tool run that timed out no longer leaves a hash-map
allocation in the DebugAllocator leak report. clanker doctorno longer treats a backup snapshot named with an impossible
calendar date (31 April, 29 February in a non-leap year) as the newest
snapshot. Those names used to overflow into a later real day and win the
lexicographic newest-name scan.- The Runs list labels a run "yesterday" on calendar day, not after 24 wall
hours. The morning after a spring-forward a Sunday run was still "23 hours
ago".
v0.2.1
Fixed
- The
improveworktree's base-ref probe askedgit rev-parseabout the
process's current directory rather than a named repository. The only
behavior change is to its test, which built a fixture repository and then
asserted against whichever repository it happened to run inside: green on a
checkout that hadorigin/main, red on one that did not, which is what a
tag checkout is.v0.2.0was tagged but never published for this reason.