Repository navigation
ClusterVision 0.18.0 is the release an agent can trust. Every listing, count and search answer
is either exact or says what it skipped: counts are prompts and replies on every harness, a
session the store has not counted shows a dash, and search reads what the index has not seen.
One stored-format version replaces five; upgrading reads every session once. A write to a store
costs the session it touched, not the store: SQLite stores carry per-session certificates and
transcripts resume from their last mark, so cv index is cheap enough to run hourly or not at
all. No hidden limit decides what you get; the bounds that remain are flags you set or caps that
never change a result. Removed names exit 2 with a pointer; stored logs keep reading. Hooks cover
Codex as well as Claude, and cv doctor reports a harness release cv has not verified.
Breaking: commands, MCP, HTTP and JSON. A removed name exits 2 with a pointer to its replacement.
cv search --json(and MCPsearch) prints{"hits": [...], "total": M}, not an array; the table footer readsN of M matches./api/searchaddsX-Cv-Search-Total, every session that matched; its note saysN of M matcheswhenlimitcut it.cv events --json(/api/events, MCP) holds whole commands and error texts, newlines kept; the table marks cuts with…, and--wideprints them whole.cv search --scan(scan=1,cv packwithout an index) matches each session's whole exchange, streamed, instead of its first 256 KiB.cv index --semanticreads each session as far as the model embeds (512 tokens × median token length) and prints it; the 64 KiB head is gone.- The full-text index holds a persisted tool output whole, not its first MiB, and snippets find a term anywhere;
source::VERSION9 rereads once. - Hooks read at most 8 MiB of transcript and say what they left unread:
compactnames the tail it read,starta row's commit search span. cv showon a pipe prints the whole transcript (no 200 KB head+tail guard); MCPshowadds no defaultlast/max_byteswindow.- MCP
observe_streamreturns everything appended by default;char_cap, when given, is stated with atruncatedcount. - Cursor counts only bubbles a read keeps (capability markers dropped); a composer with external bubble cells counts at
cv index. source::VERSIONis 8: listings rediscover once, so rc.2's cached Cursor counts are recounted.message_countcounts prompts and replies only (no tool results or sub-agent returns) and isnull, not0, until counted:ls --json,/api/sessions, search rows.cv archive lscounts turns likecv ls;catalog.jsonlkeeps the raw count asmessages_written; 0.17 rows show a dash until resynced.extra.openclawkeys keep native camelCase (stopReason,customType,error.errorCode);custom_detailsandbranch_from_idbecomedetailsandfromId.- An IR or OpenSession 0.3 message without
kindororiginis refused, not inferred from its role. - Fidelity-report
deltasandcv formatsfindings are{what, a, b, expected, where}, replacing{field, before, after}and the old finding keys. - MCP tools omit
--follow; afollowargument is refused, namingfor. cv scryon a pipe prints the sessions it would follow and exits 0;--followfollows,--for 30s|5m|2hbounds it.- Watch and
observe_streamcursors are version 2; a 0.17 cursor starts a fresh baseline. - A tag-only
decision(pre-0.15, nothing posed) reads as an assigned action, not a decision owed; the page's tagged-decision card is gone. $CLAURDVOYANT_HOMEand$CLAURDVOYANT_MAX_STALE_SECSexit 2, naming theCLUSTERVISION_variables;claurdvoyantdirectories are no longer read.- Renamed:
rewind --from-compaction(the default;--fullfor everything),deferrals --sinceis--at,dataset --outis--file. cv tools --agenttakes an exact id or unique prefix, else exits 2;--acrosswith--agent,--toolor--timelineexits 2.- An unknown
cv task events --kind(/api/events?kind=) exits 2 (400) listing the known kinds, instead of listing nothing. cv workflowexits 2 on flags it dropped: run-only flags without a run,--revive-allwithout--revive,--revivewith--json.-q text:without an index reads live; past--live-bytesor under--frozenit exits 2 namingcv index(/api/stats: 503).cv events,cv touched,cv blameand their HTTP routes fail on an event-catalog error instead of answering empty.
Breaking (library): cv-core, cv-search and cv-testkit.
ParseOptions/ExtraProjection→Demand { tier, spans, offsets };MessageSink::extra_projection→tier; the fiveWatcherpoll methods →poll/try_poll(Poll { .. }).Adapter::resume/try_resume/resume_format→Adapter::transcript(r, demand, Start, sink);append_onlyreturnsbool.Adapter::discoverreturnsDiscovered { refs, skipped }(out-of-tree:Ok(refs.into()));cline::discover_inreturns it,cline_sdk::discoverfills&mut Discovered.Watcher::runis gone (callers schedulepoll);poll_sources→offer_sources.Text: over 4 KiB isText::Source;Spanis wire form only; malformed escapes and unresolved formatting error;matches_strandis_lazyreplace equality andis_span.lazy::json_string_spanis gone;try_resolve_prefixbudgets decoded bytes (max_raw→max);lazy::read_head→read_head_checked(Result).ir::Head→projection::Head(separate byte and character budgets;pushreturnstruewhen full);Counted::newbuildsCounted;hashing()captures SHA-256.emit::Deltaandformats::Finding→emit::Divergence {what, a, b, expected, at};FindingKind::ManifestInvalidreplacessource_file_missingfor unparseable manifests.SubagentInfo/claude::subagent_refs→ir::AgentRef/subagent_tree_of;claude::CARRIER_KEY→ir::CARRIER_KEY;SubagentEnd,ApiErrorNotice,TaskNoticemove tolanes.- Return
Result: agent end, return, task-notice and workflow-launch reads; forest and subagent-reference APIs;one_agent_across;wire::openai::tool_calls;store_affordances;json_files. - Return
Result:codex::parse_str,gemini::parse_all_str[_for],ingest::ingest_files,events::{events_for, sessions_touching, sessions_editing, edits_touching_file}. - Renamed modules:
handoff→codex_handoff,loom→splice,harness::harmony→harness::wire::harmony;decode_contenttakes a call-id generator (ir::derived_call_id). export::{ChatGptExport, ClaudeExport}are gone:harness::for_harness_with_root(Harness::ChatGptExport, dir).affordance:classify_tool,items_of,item_of→classify_tool_json/_view,items_of_view,item_of_view;Returns::ResultInPromptis new (Roo'snew_task).affordance::{unwrap,rewrap}_deferredtake aDeferredWrapper;wire::anthropic's ownedTexter,block_from*andblocks_fromare gone.distill::distill→prepare_distill+distill_pack;Session::first_user_textandsearchable_textare gone.SearchRow::to_json→to_json_with(&SearchRowContext);scan::live_search→live_search_filtered.- Redaction and HTML rendering take a resolver (
share_message(.., resolver)); Markdown useswrite_md_message/write_md_block;scrub_value/scrub_coware private (redact_with,redact_message,redact_text). RedactOptions.keep_emails→classes.emails, inverted;task::AppendOutcome.replay_warningsis gone.source::Published→Record<T>(Table<T: Payload>,admitreplacespublished/fresh);source::rename_consumeris gone;catalog::fill_countis gone.resume::versionreturnsString;resume::MarkUpdateis{session, mark};publish::retractis gone (publish::Setowns rollback).- New fields break exhaustive literals:
EmitOptions.parsed_at,PruneOptions/RewindOptions.skills_policyand results'skills,Stats.uncounted,HarnessCensus.first_error,LaneWork.unread. EmitOptions.sidechain_ofisOption<SidechainOf {root, agent}>;prune::prune_sessiontakes theHarnessfirst.events::ingest_alltakesIngestOptions;query::WindowPresenceis gone (filter_refs_limiteddrops it);query::HAS_FLAGSrows are(name, help, Cost).lanes::Lane.statusisLaneStatus,LaneEvent.eventisLaneEventKind;STRAND_PATTERNSis private (text_is_waiting).ForestTools::for_workflow→tools::forest_tools_selected(r, None, Some(run_id), None);task::store::append_agent_event→TaskStore::default_store().append_agent_event.- cv-search:
text_search*,enrich_text_snippets,semantic_search_filtered→Searcher::{search, search_in};embed_all→embed_sessions;Searcher::semanticis private (Searcher::from). fts::enrich_text_snippetsreturnsResult<Option<String>>(a degradation note).- cv-testkit:
heap::begin/endreturnMeasurement;Env::enter_isolatedreturnsIsolated(armed, Scope);claude::user(sid, uuid, ts, text).
After upgrading, once.
source::VERSIONis 7: the first listing rebuilds the catalog (said on stderr;cv indexdoes it ahead) and every mark, checkpoint and watch state.- The first
cv indexrebuilds the full-text index whole.
Listing and counts.
-
A plain
.jsonOpenSession document is discovered wherever its top-level version key sits, not only within the first 64 KiB. -
A first
cv lsleaves Codex, Grok, Kimi, Kimi Code, Qwen, Hermes, Goose, Zed, Continue and OpenCode uncounted until a read orcv index. -
cv statsreports "N not counted yet" (uncountedin--json,/api/stats);--sort-by messagesranks uncounted last. -
A count survives refreshes of an unchanged source and is dropped when it changes; rewound or superseded Hermes rows no longer inflate it.
-
Kimi, Kimi Code and Grok titles are the recorded native title; Hermes, Goose and Zed list from metadata alone.
-
Cursor legacy counts exclude empty and malformed bubbles.
-
A listing racing
cv indexwaits up to 5 s for it instead of discarding its update. -
created:without a recorded creation time no longer matches on update time. -
ls --json --ascwith a query selects the same sessions as descending; absent sessions take no window slot; refreshed harnesses keep their tie order. -
serve,mcpand followers see Gemini and Qwen projects registered after they started. -
A read-only catalog still serves warm listings; builds without
sqliteno longer spool unpublishable events. -
Semantic indexing caps transcript heads at 64 KiB of decoded text.
-
cv search,/api/searchand-q text:also read what the index has not seen, within--live-bytes(256 MiB);--frozenreads none. -
cv searchwithout an index answers from that live read instead of exiting 1. -
Search staleness counts each session's preferred copy, not older duplicates.
-
Cold SQLite snapshots stage beside the catalog instead of in a multi-gigabyte tmpfs copy.
-
MCP
observe_streamkeeps every followed session's reader state server-side and reportsrereads. -
Codex rollouts over 8 MiB list the title and cwd a full read gives, not a head-and-tail sample.
-
An append or rewrite rereads only that session: Claude forks, Grok cwd groups and Kimi Code sub-agents no longer reread; Codex rereads appended records.
-
A store write rereads only changed sessions: Hermes, Goose, OpenCode, Devin, Zed, Cursor, OpenClaw, Cline SDK databases, Gemini and Qwen
logs.json. -
Discovery rescans only changed sources: Kimi, Kimi Code, Goose legacy, Cline, Roo, Continue, OpenSession files and OpenClaw stores.
-
Sub-agent trees (
show --tree,--subagents, lanes) reuse unchanged agents' saved scans; Codex, Hermes, Devin and OpenClaw read their registries once per state. -
cv indexand live search read only what was appended since the last index; compressed Codex rollouts are read in parallel. -
One changed session rewrites only its catalog row;
cv show agent-…, workflow-name and ghost lookups read the catalog, not rediscovery. -
The prompt hook, task mutations,
cv task listandGET /api/tasksreplay only task-log events appended since a stored fold. -
The sessions API resumes its 1024 most recent sessions of any size;
cv stats --tokenskeeps every live session's cached usage. -
Watch checkpoints and archive resume states of any size are kept (past 64 KiB or 1 MiB they were dropped).
-
A WAL-backed SQLite copy happens once per command; an export archive past the 8 MB cache is scanned once.
-
cv show --treeindents once per fork above a message, so a straight chain prints flat.
Reading.
cv indexholds a few open files per worker, not two per compressed Codex rollout, so a cold index stays under macOS's 256-file limit.cv search,/api/search, MCP search and-q text:read every session the index has not seen;--live-bytes(live_bytes) now only bounds it when given.- Global
--frozen(CV_FROZEN=1) reads without updating cv stores, streaming stale events; commands that write stores or sessions exit 2. - Boundaries carry no invented text (Claude, OpenClaw, Goose, Hermes, Kimi, Kimi Code, Qwen);
showlabels them by kind and marks inferred ones synthesized. - Cursor and LM Studio (Harmony) tool calls without native ids get
cv:<format>:<position>. - Codex: tool results carry only recorded status; usage-only records are notices;
[error]outputs stay verbatim unless cv wrote the rollout. - Zed and Goose report the recorded model; the provider (
extra.zed.provider, Goose metadata) never substitutes for it. - Gemini, Qwen, Goose, Grok, LM Studio, OpenClaw and OpenCode report the model on every turn that records it, windowed reads included.
cv distillandcv adopt --modeldefault the agent type togeneral-purposeonly when the source names none.- A source replaced or deleted mid-read is an error, checked after slow callbacks, per mapped window, at checkpoints and at EOF.
- Native Codex file-change records, code-mode edits included, feed
cv touched, tool histograms and query facts without duplicating patch calls. - Qwen checkpoint facts live under the
qwenbag, notgemini. - Compressed Codex rollouts need the
zstdfeature; without it they are unreadable, not parsed as JSONL. - ZIP uploads over 10,000 entries are refused.
cv blame -Lsays when its commit list was cut and marks an empty message(no message);cv showhints spell sub-agent ids in full.- Claude Code 2.1.304 is the verified writer: request-ledger,
isolation-latchand unknown records are carried, never read as turns. - A Claude fork sub-agent's
fork-context-refsetslineage.forked_fromandextra.claude.fork_context; a retried request'sapi_errorrenders as an error. - Claude fork inference counts only a copied first prompt or boundary, not a SessionStart hook's earlier timestamp.
- A workflow agent turns stale when its session's
tool-resultsgains spilled outputs.
Titles and affordances.
has:subagentsmatches the forestagentscounts: Claude workflow agents and Codex and Devin forests too.- Kimi, Kimi Code and Hermes sub-agents join the forest;
dataset --subagentsreads every harness's forest. - Emitted sessions' fallback title is the
cv lstitle; Cursor CLI titles drop the leading<timestamp>. has:skilland--kind affordancescount a Claude skill loaded by slash command, once per activation.- Kimi Code: the latest
TodoListis aplan/staterow; legacyAgent/AgentSwarmcalls are spawns, their results returns. - Roo: a
new_taskresult beside user text is asubagent_returndetail; the turn stays a prompt. - Tool-filtered histograms keep edit counts; native edits reconcile by call and resolved path, never guessing relative paths in compound shell commands.
Reshaping.
cv pack --excerpt-bytes N(default 1600) bounds each excerpt message; the bundle'sBounds:line names every bound and what it cut.CV_PACK_LLMdigests send up to the model's provider-reported context window (was 60K chars), or--context-bytes N; the bundle states bytes sent and the limit.cv port --stricthelp names the actual⚠ lossy:output marker for losses the target format cannot hold.prune,rewindandporttake--skills keep|drop|drop-stale(defaultkeep), legacy command-file skills included.cv prune,cv rewind,cv adoptand Claude ports check the staged session resumes before publishing; else they refuse and leave nothing.cv prune,cv rewindand adoption refuse a non-JSON-record line;cv prunerefuses an empty transcript; minted ids are UUID v7.cv rewindcopies to the end of the file (tail records likecost-statewere dropped).cv rewindat a cut keeps parallel calls, closes open ones, drops a malformed later line, and asks for a rerun on an unterminated one.cv rewindrefuses a bodyless turn only with--thinking portable; a native copy keeps it.cv portto Codex writes the source'scli_version; to OpenClaw and LM Studio, no inventedusage.totalTokensortokenCount: 0.cv portto Gemini derives message ids (UUID v5) from session and turn, so re-emits match; to Continue, a tool turn without result is refused.- Gemini, Grok, OpenClaw, Cline, Roo and Continue emits stage their files, publish the transcript or index last, and roll back on failure.
- Staged emits are not crash-atomic: a crash can leave a published prefix; a failed rollback is reported.
- OpenClaw port and emit refuse an unreadable or concurrently changed
sessions.json; an unwritable Geminiprojects.jsonfails the emit. - Hermes and OpenCode exports reject unreadable sources before creating any output;
--forcerestores a replaced sidecar when the transcript fails. - Claude, Gemini and Qwen resume hints are one runnable line:
cd <dir> && <harness> --resume <id>. - Qwen emission keeps absent cache counts absent; OpenCode keeps an unknown cwd empty instead of cv's own.
cv splice --generaterejects an empty completion;pack --jsonreturns content, artifact paths and resume hints;cv packnamesLMSTUDIO_API_BASE.- A refused write names the failed JSONL record, or the OS error behind a refused exclusive rename.
Doctor and hooks.
cv doctoradds Writer versions: the newest Claude and Codex versions seen versus the newest verified, plus unknown sessions.cv hooks install codex(user or--scope project) installs Claude's five hooks: compaction recovery, start context, lanes, decisions, edit guard.cv hooks install|show codexandcv doctorreport each Codex hook as trusted, untrusted or modified, with Codex's review step.- Codex's edit guard denies a conflicting edit (Codex has no
ask), but not one over a file the same root thread's agents edited. cv hooksandcv hook --harnessaccept every--harnessspelling (cc,claude-code);cv lanes --recent Nreads Codex sessions too.
Waiting commands.
- Every waiting command says on stderr within a second what it waits for; on a pipe, each exits within 5 s or announces itself.
cv workflow --followtakes--for <duration>, then renders the run as it stands.cv hookwith a terminal on stdin exits 2;cv mcpandcv task … -say what they read.- Followers announce a session unreadable at start once it reads, instead of guessing its message count.
cv eventskeeps every extracted event (the per-message(kind, target)dedup is gone).- A follower's byte mark on a compressed Codex rollout is unresolved, not resumed from a decoded prefix.
Removed.
cv watch --intervaltakes seconds likescry; a negative--intervalexits 2.- An unknown
cv pack --formatexits 2 namingmd,prompt,session. - Mentions of a leftover
index.sqliteor pre-0.9.12discover.jsonare gone; delete either by hand. - MCP errors for removed properties name their replacements.
Skips: counted, reported, or warned once.
cv indexdefers a session whose old search baseline cannot be invalidated (catalog unopenable), names it, and completes the pass instead of aborting.- A source discovery cannot open (unreadable dir, locked or corrupt database, bad export or
sessions.json) is named bycv doctor, not silently empty. cv doctor --jsongainsskipped_sources; per-filecv: skippinglines become one stderr summary.- An unreadable session file errors instead of reading empty: Continue, OpenCode, Cline, Roo, Devin, Hermes, Goose, legacy Codex
.json. - Undecodable records count as
skipped_lines: Claude (trailing partial included), Cursor, Continue, OpenCode, Cline, Roo, Goose, Zed. - A catalog, usage-cache, scan-cache or
config.tomlfailure is said once per process and retried; nothing partial is published. - A Hermes compression continuation that cannot be queried errors instead of dropping
continued_in. - Search names a hit whose source cannot be read;
--scanskips unreadable sessions and names them. cv formatsreports each harness's first parse error (first_errorin--json).ls --json --enrichcarriesenrich_errorfor an unreadable transcript.cv workflow --revivesays when a lane's read stopped early; an unreadable run-state file is named, not claimed as a ghost launch.cv archive,cv pack,cv catandcv events --subagentsname their read failures instead of dropping them.cv servecloses a connection whose body exceeds its Content-Length.
Tooling and CI.
- The viewing-and-sharing manual links Compare branches to the renamed Splice composer section.
cv schema --jsonlistsroutes(everycv servemethod and path) and thesubagent_rowandtask_rowkeys.cv index --jsonreportschanged,removedanderrorsbesideindexed.- Release gates: 0.17.0 compatibility, 0.16.1 upgrade over every corpus, real Codex 0.162.1 hooks, and macOS nightly and on rc tags.
- Contributors:
tools/size-budget.txtandcheck-size.py --writeare gone (drift is reported);tools/dump-hash.shis the byte-identity gate.
rc.1 tagged 2026-10-22; rc.2 2026-10-23.
Install clustervision 0.18.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/emberian/cv/releases/download/v0.18.0/clustervision-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/emberian/cv/releases/download/v0.18.0/clustervision-installer.ps1 | iex"Download clustervision 0.18.0
| File | Platform | Checksum |
|---|---|---|
| clustervision-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| clustervision-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| clustervision-i686-pc-windows-msvc.zip | x86 Windows | checksum |
| clustervision-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| clustervision-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| clustervision-i686-unknown-linux-gnu.tar.xz | x86 Linux | checksum |
| clustervision-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |