Skip to content

Releases: emberian/cv

0.18.0 — 2026-10-23 — the release an agent can trust

Choose a tag to compare

@github-actions github-actions released this 23 Oct 11:26

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 MCP search) prints {"hits": [...], "total": M}, not an array; the table footer reads N of M matches.
  • /api/search adds X-Cv-Search-Total, every session that matched; its note says N of M matches when limit cut it.
  • cv events --json (/api/events, MCP) holds whole commands and error texts, newlines kept; the table marks cuts with …, and --wide prints them whole.
  • cv search --scan (scan=1, cv pack without an index) matches each session's whole exchange, streamed, instead of its first 256 KiB.
  • cv index --semantic reads 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::VERSION 9 rereads once.
  • Hooks read at most 8 MiB of transcript and say what they left unread: compact names the tail it read, start a row's commit search span.
  • cv show on a pipe prints the whole transcript (no 200 KB head+tail guard); MCP show adds no default last/max_bytes window.
  • MCP observe_stream returns everything appended by default; char_cap, when given, is stated with a truncated count.
  • Cursor counts only bubbles a read keeps (capability markers dropped); a composer with external bubble cells counts at cv index.
  • source::VERSION is 8: listings rediscover once, so rc.2's cached Cursor counts are recounted.
  • message_count counts prompts and replies only (no tool results or sub-agent returns) and is null, not 0, until counted: ls --json, /api/sessions, search rows.
  • cv archive ls counts turns like cv ls; catalog.jsonl keeps the raw count as messages_written; 0.17 rows show a dash until resynced.
  • extra.openclaw keys keep native camelCase (stopReason, customType, error.errorCode); custom_details and branch_from_id become details and fromId.
  • An IR or OpenSession 0.3 message without kind or origin is refused, not inferred from its role.
  • Fidelity-report deltas and cv formats findings are {what, a, b, expected, where}, replacing {field, before, after} and the old finding keys.
  • MCP tools omit --follow; a follow argument is refused, naming for.
  • cv scry on a pipe prints the sessions it would follow and exits 0; --follow follows, --for 30s|5m|2h bounds it.
  • Watch and observe_stream cursors 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_HOME and $CLAURDVOYANT_MAX_STALE_SECS exit 2, naming the CLUSTERVISION_ variables; claurdvoyant directories are no longer read.
  • Renamed: rewind --from-compaction (the default; --full for everything), deferrals --since is --at, dataset --out is --file.
  • cv tools --agent takes an exact id or unique prefix, else exits 2; --across with --agent, --tool or --timeline exits 2.
  • An unknown cv task events --kind (/api/events?kind=) exits 2 (400) listing the known kinds, instead of listing nothing.
  • cv workflow exits 2 on flags it dropped: run-only flags without a run, --revive-all without --revive, --revive with --json.
  • -q text: without an index reads live; past --live-bytes or under --frozen it exits 2 naming cv index (/api/stats: 503).
  • cv events, cv touched, cv blame and 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 five Watcher poll methods → poll/try_poll(Poll { .. }).
  • Adapter::resume/try_resume/resume_format → Adapter::transcript(r, demand, Start, sink); append_only returns bool.
  • Adapter::discover returns Discovered { refs, skipped } (out-of-tree: Ok(refs.into())); cline::discover_in returns it, cline_sdk::discover fills &mut Discovered.
  • Watcher::run is gone (callers schedule poll); poll_sources → offer_sources.
  • Text: over 4 KiB is Text::Source; Span is wire form only; malformed escapes and unresolved formatting error; matches_str and is_lazy replace equality and is_span.
  • lazy::json_string_span is gone; try_resolve_prefix budgets decoded bytes (max_raw → max); lazy::read_head → read_head_checked (Result).
  • ir::Head → projection::Head (separate byte and character budgets; push returns true when full); Counted::new builds Counted; hashing() captures SHA-256.
  • emit::Delta and formats::Finding → emit::Divergence {what, a, b, expected, at}; FindingKind::ManifestInvalid replaces source_file_missing for unparseable manifests.
  • SubagentInfo/claude::subagent_refs → ir::AgentRef/subagent_tree_of; claude::CARRIER_KEY → ir::CARRIER_KEY; SubagentEnd, ApiErrorNotice, TaskNotice move to lanes.
  • 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_content takes 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::ResultInPrompt is new (Roo's new_task).
  • affordance::{unwrap,rewrap}_deferred take a DeferredWrapper; wire::anthropic's owned Texter, block_from* and blocks_from are gone.
  • distill::distill → prepare_distill + distill_pack; Session::first_user_text and searchable_text are 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 uses write_md_message/write_md_block; scrub_value/scrub_cow are private (redact_with, redact_message, redact_text).
  • RedactOptions.keep_emails → classes.emails, inverted; task::AppendOutcome.replay_warnings is gone.
  • source::Published → Record<T> (Table<T: Payload>, admit replaces published/fresh); source::rename_consumer is gone; catalog::fill_count is gone.
  • resume::version returns String; resume::MarkUpdate is {session, mark}; publish::retract is gone (publish::Set owns rollback).
  • New fields break exhaustive literals: EmitOptions.parsed_at, PruneOptions/RewindOptions.skills_policy and results' skills, Stats.uncounted, HarnessCensus.first_error, LaneWork.unread.
  • EmitOptions.sidechain_of is Option<SidechainOf {root, agent}>; prune::prune_session takes the Harness first.
  • events::ingest_all takes IngestOptions; query::WindowPresence is gone (filter_refs_limited drops it); query::HAS_FLAGS rows are (name, help, Cost).
  • lanes::Lane.status is LaneStatus, LaneEvent.event is LaneEventKind; STRAND_PATTERNS is 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::semantic is private (Searcher::from).
  • fts::enrich_text_snippets returns Result<Option<String>> (a degradation note).
  • cv-testkit: heap::begin/end return Measurement; Env::enter_isolated returns Isolated(armed, Scope); claude::user(sid, uuid, ts, text).

After upgrading, once.

  • source::VERSION is 7: the first listing rebuilds the catalog (said on stderr; cv index does it ahead) and every mark, checkpoint and watch state.
  • The first cv index rebuilds the full-text index whole.

Listing and counts.

  • A plain .json OpenSession document is discovered wherever its top-level version key sits, not only within the first 64 KiB.
  • A first cv ls leaves Codex, Grok, Kimi, Kimi Code, Qwen, Hermes, Goose, Zed, Continue and OpenCode uncounted until a read or cv index.
  • cv stats reports "N not counted yet" (uncounted in --json, /api/stats); --sort-by messages ranks 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 coun...
Read more

0.18.0-rc.5 — 2026-10-23 — the release an agent can trust

Choose a tag to compare

@github-actions github-actions released this 23 Oct 10:56

Release Notes

Breaking: commands, MCP, HTTP and JSON. A removed name exits 2 with a pointer to its replacement.
Breaking: commands, MCP, HTTP and JSON.

  • cv index holds a few open files per worker, not two per compressed Codex rollout, so a cold index stays under macOS's 256-file limit.
  • cv index defers a session whose old search baseline cannot be invalidated (catalog unopenable), names it, and completes the pass instead of aborting.
  • cv search --json (and MCP search) prints {"hits": [...], "total": M}, not an array; the table footer reads N of M matches.
  • /api/search adds X-Cv-Search-Total, every session that matched; its note says N of M matches when limit cut it.
  • cv pack --excerpt-bytes N (default 1600) bounds each excerpt message; the bundle's Bounds: line names every bound and what it cut.
  • CV_PACK_LLM digests 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.
  • A plain .json OpenSession document is discovered wherever its top-level version key sits, not only within the first 64 KiB.
  • cv events --json (/api/events, MCP) holds whole commands and error texts, newlines kept; the table marks cuts with …, and --wide prints them whole.
  • 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.
  • cv search --scan (scan=1, cv pack without an index) matches each session's whole exchange, streamed, instead of its first 256 KiB.
  • cv index --semantic reads 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::VERSION 9 rereads once.
  • Hooks read at most 8 MiB of transcript and say what they left unread: compact names the tail it read, start a row's commit search span.
  • cv show on a pipe prints the whole transcript (no 200 KB head+tail guard); MCP show adds no default last/max_bytes window.
  • MCP observe_stream returns everything appended by default; char_cap, when given, is stated with a truncated count.
  • Cursor counts only bubbles a read keeps (capability markers dropped); a composer with external bubble cells counts at cv index.
  • source::VERSION is 8: listings rediscover once, so rc.2's cached Cursor counts are recounted.
  • message_count counts prompts and replies only (no tool results or sub-agent returns) and is null, not 0, until counted: ls --json, /api/sessions, search rows.
  • cv archive ls counts turns like cv ls; catalog.jsonl keeps the raw count as messages_written; 0.17 rows show a dash until resynced.
  • extra.openclaw keys keep native camelCase (stopReason, customType, error.errorCode); custom_details and branch_from_id become details and fromId.
  • An IR or OpenSession 0.3 message without kind or origin is refused, not inferred from its role.
  • Fidelity-report deltas and cv formats findings are {what, a, b, expected, where}, replacing {field, before, after} and the old finding keys.
  • MCP tools omit --follow; a follow argument is refused, naming for.
  • cv scry on a pipe prints the sessions it would follow and exits 0; --follow follows, --for 30s|5m|2h bounds it.
  • Watch and observe_stream cursors 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_HOME and $CLAURDVOYANT_MAX_STALE_SECS exit 2, naming the CLUSTERVISION_ variables; claurdvoyant directories are no longer read.
  • Renamed: rewind --from-compaction (the default; --full for everything), deferrals --since is --at, dataset --out is --file.
  • cv tools --agent takes an exact id or unique prefix, else exits 2; --across with --agent, --tool or --timeline exits 2.
  • An unknown cv task events --kind (/api/events?kind=) exits 2 (400) listing the known kinds, instead of listing nothing.
  • cv workflow exits 2 on flags it dropped: run-only flags without a run, --revive-all without --revive, --revive with --json.
  • -q text: without an index reads live; past --live-bytes or under --frozen it exits 2 naming cv index (/api/stats: 503).
  • cv events, cv touched, cv blame and 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 five Watcher poll methods → poll/try_poll(Poll { .. }).
  • Adapter::resume/try_resume/resume_format → Adapter::transcript(r, demand, Start, sink); append_only returns bool.
  • Adapter::discover returns Discovered { refs, skipped } (out-of-tree: Ok(refs.into())); cline::discover_in returns it, cline_sdk::discover fills &mut Discovered.
  • Watcher::run is gone (callers schedule poll); poll_sources → offer_sources.
  • Text: over 4 KiB is Text::Source; Span is wire form only; malformed escapes and unresolved formatting error; matches_str and is_lazy replace equality and is_span.
  • lazy::json_string_span is gone; try_resolve_prefix budgets decoded bytes (max_raw → max); lazy::read_head → read_head_checked (Result).
  • ir::Head → projection::Head (separate byte and character budgets; push returns true when full); Counted::new builds Counted; hashing() captures SHA-256.
  • emit::Delta and formats::Finding → emit::Divergence {what, a, b, expected, at}; FindingKind::ManifestInvalid replaces source_file_missing for unparseable manifests.
  • SubagentInfo/claude::subagent_refs → ir::AgentRef/subagent_tree_of; claude::CARRIER_KEY → ir::CARRIER_KEY; SubagentEnd, ApiErrorNotice, TaskNotice move to lanes.
  • 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_content takes 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::ResultInPrompt is new (Roo's new_task).
  • affordance::{unwrap,rewrap}_deferred take a DeferredWrapper; wire::anthropic's owned Texter, block_from* and blocks_from are gone.
  • distill::distill → prepare_distill + distill_pack; Session::first_user_text and searchable_text are 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 uses write_md_message/write_md_block; scrub_value/scrub_cow are private (redact_with, redact_message, redact_text).
  • RedactOptions.keep_emails → classes.emails, inverted; task::AppendOutcome.replay_warnings is gone.
  • source::Published → Record<T> (Table<T: Payload>, admit replaces published/fresh); source::rename_consumer is gone; catalog::fill_count is gone.
  • resume::version returns String; resume::MarkUpdate is {session, mark}; publish::retract is gone (publish::Set owns rollback).
  • New fields break exhaustive literals: EmitOptions.parsed_at, PruneOptions/RewindOptions.skills_policy and results' skills, Stats.uncounted, HarnessCensus.first_error, LaneWork.unread.
  • EmitOptions.sidechain_of is Option<SidechainOf {root, agent}>; prune::prune_session takes the Harness first.
  • events::ingest_all takes IngestOptions; query::WindowPresence is gone (filter_refs_limited drops it); query::HAS_FLAGS rows are (name, help, Cost).
  • lanes::Lane.status is LaneStatus, LaneEvent.event is LaneEventKind; STRAND_PATTERNS is 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::semantic is private (Searcher::from).
  • fts::enrich_text_snippets returns Result<Option<String>> (a degradation note).
  • cv-testkit: heap::begin/end return Measurement; Env::enter_isolated returns Isolated(armed, Scope); claude::user(sid, uuid, ts, text).

After upgrading, once.

  • source::VERSION is 7: the first listing rebuilds the catalog (said on stderr; cv index does it ahead) and every mark, checkpoint and watch state.
  • The first cv index rebuilds the full-text index whole.

Listing and counts.

  • A first cv ls leaves Codex, Grok, Kimi, Kimi Code, Qwen, Hermes, Goose, Zed, Continue and OpenCode uncounted until a read or cv index.
  • cv stats reports "N not counted yet" (uncounted in --json, /api/stats); --sort-by messages ranks 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 bub...
Read more

0.18.0-rc.4 — 2026-10-23 — the release an agent can trust

Choose a tag to compare

@github-actions github-actions released this 23 Oct 07:55

Release Notes

Breaking: commands, MCP, HTTP and JSON. A removed name exits 2 with a pointer to its replacement.
Breaking: commands, MCP, HTTP and JSON.

  • cv search --json (and MCP search) prints {"hits": [...], "total": M}, not an array; the table footer reads N of M matches.
  • /api/search adds X-Cv-Search-Total, every session that matched; its note says N of M matches when limit cut it.
  • cv pack --excerpt-bytes N (default 1600) bounds each excerpt message; the bundle's Bounds: line names every bound and what it cut.
  • CV_PACK_LLM digests 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.
  • A plain .json OpenSession document is discovered wherever its top-level version key sits, not only within the first 64 KiB.
  • cv events --json (/api/events, MCP) holds whole commands and error texts, newlines kept; the table marks cuts with …, and --wide prints them whole.
  • 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.
  • cv search --scan (scan=1, cv pack without an index) matches each session's whole exchange, streamed, instead of its first 256 KiB.
  • cv index --semantic reads 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::VERSION 9 rereads once.
  • Hooks read at most 8 MiB of transcript and say what they left unread: compact names the tail it read, start a row's commit search span.
  • cv show on a pipe prints the whole transcript (no 200 KB head+tail guard); MCP show adds no default last/max_bytes window.
  • MCP observe_stream returns everything appended by default; char_cap, when given, is stated with a truncated count.
  • Cursor counts only bubbles a read keeps (capability markers dropped); a composer with external bubble cells counts at cv index.
  • source::VERSION is 8: listings rediscover once, so rc.2's cached Cursor counts are recounted.
  • message_count counts prompts and replies only (no tool results or sub-agent returns) and is null, not 0, until counted: ls --json, /api/sessions, search rows.
  • cv archive ls counts turns like cv ls; catalog.jsonl keeps the raw count as messages_written; 0.17 rows show a dash until resynced.
  • extra.openclaw keys keep native camelCase (stopReason, customType, error.errorCode); custom_details and branch_from_id become details and fromId.
  • An IR or OpenSession 0.3 message without kind or origin is refused, not inferred from its role.
  • Fidelity-report deltas and cv formats findings are {what, a, b, expected, where}, replacing {field, before, after} and the old finding keys.
  • MCP tools omit --follow; a follow argument is refused, naming for.
  • cv scry on a pipe prints the sessions it would follow and exits 0; --follow follows, --for 30s|5m|2h bounds it.
  • Watch and observe_stream cursors 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_HOME and $CLAURDVOYANT_MAX_STALE_SECS exit 2, naming the CLUSTERVISION_ variables; claurdvoyant directories are no longer read.
  • Renamed: rewind --from-compaction (the default; --full for everything), deferrals --since is --at, dataset --out is --file.
  • cv tools --agent takes an exact id or unique prefix, else exits 2; --across with --agent, --tool or --timeline exits 2.
  • An unknown cv task events --kind (/api/events?kind=) exits 2 (400) listing the known kinds, instead of listing nothing.
  • cv workflow exits 2 on flags it dropped: run-only flags without a run, --revive-all without --revive, --revive with --json.
  • -q text: without an index reads live; past --live-bytes or under --frozen it exits 2 naming cv index (/api/stats: 503).
  • cv events, cv touched, cv blame and 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 five Watcher poll methods → poll/try_poll(Poll { .. }).
  • Adapter::resume/try_resume/resume_format → Adapter::transcript(r, demand, Start, sink); append_only returns bool.
  • Adapter::discover returns Discovered { refs, skipped } (out-of-tree: Ok(refs.into())); cline::discover_in returns it, cline_sdk::discover fills &mut Discovered.
  • Watcher::run is gone (callers schedule poll); poll_sources → offer_sources.
  • Text: over 4 KiB is Text::Source; Span is wire form only; malformed escapes and unresolved formatting error; matches_str and is_lazy replace equality and is_span.
  • lazy::json_string_span is gone; try_resolve_prefix budgets decoded bytes (max_raw → max); lazy::read_head → read_head_checked (Result).
  • ir::Head → projection::Head (separate byte and character budgets; push returns true when full); Counted::new builds Counted; hashing() captures SHA-256.
  • emit::Delta and formats::Finding → emit::Divergence {what, a, b, expected, at}; FindingKind::ManifestInvalid replaces source_file_missing for unparseable manifests.
  • SubagentInfo/claude::subagent_refs → ir::AgentRef/subagent_tree_of; claude::CARRIER_KEY → ir::CARRIER_KEY; SubagentEnd, ApiErrorNotice, TaskNotice move to lanes.
  • 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_content takes 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::ResultInPrompt is new (Roo's new_task).
  • affordance::{unwrap,rewrap}_deferred take a DeferredWrapper; wire::anthropic's owned Texter, block_from* and blocks_from are gone.
  • distill::distill → prepare_distill + distill_pack; Session::first_user_text and searchable_text are 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 uses write_md_message/write_md_block; scrub_value/scrub_cow are private (redact_with, redact_message, redact_text).
  • RedactOptions.keep_emails → classes.emails, inverted; task::AppendOutcome.replay_warnings is gone.
  • source::Published → Record<T> (Table<T: Payload>, admit replaces published/fresh); source::rename_consumer is gone; catalog::fill_count is gone.
  • resume::version returns String; resume::MarkUpdate is {session, mark}; publish::retract is gone (publish::Set owns rollback).
  • New fields break exhaustive literals: EmitOptions.parsed_at, PruneOptions/RewindOptions.skills_policy and results' skills, Stats.uncounted, HarnessCensus.first_error, LaneWork.unread.
  • EmitOptions.sidechain_of is Option<SidechainOf {root, agent}>; prune::prune_session takes the Harness first.
  • events::ingest_all takes IngestOptions; query::WindowPresence is gone (filter_refs_limited drops it); query::HAS_FLAGS rows are (name, help, Cost).
  • lanes::Lane.status is LaneStatus, LaneEvent.event is LaneEventKind; STRAND_PATTERNS is 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::semantic is private (Searcher::from).
  • fts::enrich_text_snippets returns Result<Option<String>> (a degradation note).
  • cv-testkit: heap::begin/end return Measurement; Env::enter_isolated returns Isolated(armed, Scope); claude::user(sid, uuid, ts, text).

After upgrading, once.

  • source::VERSION is 7: the first listing rebuilds the catalog (said on stderr; cv index does it ahead) and every mark, checkpoint and watch state.
  • The first cv index rebuilds the full-text index whole.

Listing and counts.

  • A first cv ls leaves Codex, Grok, Kimi, Kimi Code, Qwen, Hermes, Goose, Zed, Continue and OpenCode uncounted until a read or cv index.
  • cv stats reports "N not counted yet" (uncounted in --json, /api/stats); --sort-by messages ranks 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 index waits 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 --asc with a query selects the same sessions as descending; absent sessions take no window slot; refreshe...
Read more

0.18.0-rc.3 — 2026-10-23 — the release an agent can trust

Choose a tag to compare

@github-actions github-actions released this 23 Oct 05:38

Release Notes

Breaking: commands, MCP, HTTP and JSON. A removed name exits 2 with a pointer to its replacement.

  • Cursor counts only bubbles a read keeps (capability markers dropped); a composer with external bubble cells counts at cv index.
  • source::VERSION is 8: listings rediscover once, so rc.2's cached Cursor counts are recounted.
  • message_count counts prompts and replies only (no tool results or sub-agent returns) and is null, not 0, until counted: ls --json, /api/sessions, search rows.
  • cv archive ls counts turns like cv ls; catalog.jsonl keeps the raw count as messages_written; 0.17 rows show a dash until resynced.
  • extra.openclaw keys keep native camelCase (stopReason, customType, error.errorCode); custom_details and branch_from_id become details and fromId.
  • An IR or OpenSession 0.3 message without kind or origin is refused, not inferred from its role.
  • Fidelity-report deltas and cv formats findings are {what, a, b, expected, where}, replacing {field, before, after} and the old finding keys.
  • MCP tools omit --follow; a follow argument is refused, naming for.
  • cv scry on a pipe prints the sessions it would follow and exits 0; --follow follows, --for 30s|5m|2h bounds it.
  • Watch and observe_stream cursors 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_HOME and $CLAURDVOYANT_MAX_STALE_SECS exit 2, naming the CLUSTERVISION_ variables; claurdvoyant directories are no longer read.
  • Renamed: rewind --from-compaction (the default; --full for everything), deferrals --since is --at, dataset --out is --file.
  • cv tools --agent takes an exact id or unique prefix, else exits 2; --across with --agent, --tool or --timeline exits 2.
  • An unknown cv task events --kind (/api/events?kind=) exits 2 (400) listing the known kinds, instead of listing nothing.
  • cv workflow exits 2 on flags it dropped: run-only flags without a run, --revive-all without --revive, --revive with --json.
  • -q text: without an index reads live; past --live-bytes or under --frozen it exits 2 naming cv index (/api/stats: 503).
  • cv events, cv touched, cv blame and 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 five Watcher poll methods → poll/try_poll(Poll { .. }).
  • Adapter::resume/try_resume/resume_format → Adapter::transcript(r, demand, Start, sink); append_only returns bool.
  • Adapter::discover returns Discovered { refs, skipped } (out-of-tree: Ok(refs.into())); cline::discover_in returns it, cline_sdk::discover fills &mut Discovered.
  • Watcher::run is gone (callers schedule poll); poll_sources → offer_sources.
  • Text: over 4 KiB is Text::Source; Span is wire form only; malformed escapes and unresolved formatting error; matches_str and is_lazy replace equality and is_span.
  • lazy::json_string_span is gone; try_resolve_prefix budgets decoded bytes (max_raw → max); lazy::read_head → read_head_checked (Result).
  • ir::Head → projection::Head (separate byte and character budgets; push returns true when full); Counted::new builds Counted; hashing() captures SHA-256.
  • emit::Delta and formats::Finding → emit::Divergence {what, a, b, expected, at}; FindingKind::ManifestInvalid replaces source_file_missing for unparseable manifests.
  • SubagentInfo/claude::subagent_refs → ir::AgentRef/subagent_tree_of; claude::CARRIER_KEY → ir::CARRIER_KEY; SubagentEnd, ApiErrorNotice, TaskNotice move to lanes.
  • 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_content takes 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::ResultInPrompt is new (Roo's new_task).
  • affordance::{unwrap,rewrap}_deferred take a DeferredWrapper; wire::anthropic's owned Texter, block_from* and blocks_from are gone.
  • distill::distill → prepare_distill + distill_pack; Session::first_user_text and searchable_text are 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 uses write_md_message/write_md_block; scrub_value/scrub_cow are private (redact_with, redact_message, redact_text).
  • RedactOptions.keep_emails → classes.emails, inverted; task::AppendOutcome.replay_warnings is gone.
  • source::Published → Record<T> (Table<T: Payload>, admit replaces published/fresh); source::rename_consumer is gone; catalog::fill_count is gone.
  • resume::version returns String; resume::MarkUpdate is {session, mark}; publish::retract is gone (publish::Set owns rollback).
  • New fields break exhaustive literals: EmitOptions.parsed_at, PruneOptions/RewindOptions.skills_policy and results' skills, Stats.uncounted, HarnessCensus.first_error, LaneWork.unread.
  • EmitOptions.sidechain_of is Option<SidechainOf {root, agent}>; prune::prune_session takes the Harness first.
  • events::ingest_all takes IngestOptions; query::WindowPresence is gone (filter_refs_limited drops it); query::HAS_FLAGS rows are (name, help, Cost).
  • lanes::Lane.status is LaneStatus, LaneEvent.event is LaneEventKind; STRAND_PATTERNS is 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::semantic is private (Searcher::from).
  • fts::enrich_text_snippets returns Result<Option<String>> (a degradation note).
  • cv-testkit: heap::begin/end return Measurement; Env::enter_isolated returns Isolated(armed, Scope); claude::user(sid, uuid, ts, text).

After upgrading, once.

  • source::VERSION is 7: the first listing rebuilds the catalog (said on stderr; cv index does it ahead) and every mark, checkpoint and watch state.
  • The first cv index rebuilds the full-text index whole.

Listing and counts.

  • A first cv ls leaves Codex, Grok, Kimi, Kimi Code, Qwen, Hermes, Goose, Zed, Continue and OpenCode uncounted until a read or cv index.

  • cv stats reports "N not counted yet" (uncounted in --json, /api/stats); --sort-by messages ranks 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 index waits 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 --asc with a query selects the same sessions as descending; absent sessions take no window slot; refreshed harnesses keep their tie order.

  • serve, mcp and followers see Gemini and Qwen projects registered after they started.

  • A read-only catalog still serves warm listings; builds without sqlite no longer spool unpublishable events.

  • Semantic indexing caps transcript heads at 64 KiB of decoded text.

  • cv search, /api/search and -q text: also read what the index has not seen, within --live-bytes (256 MiB); --frozen reads none.

  • cv search without 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_stream keeps every followed session's reader state server-side and reports rereads.

  • 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 index and 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 list and GET /api/tasks replay only task-log events appende...

Read more

0.18.0-rc.2 — 2026-10-23 — one write costs one session

Choose a tag to compare

@github-actions github-actions released this 23 Oct 03:50

Release Notes

Breaking: commands, MCP, HTTP and JSON.

  • message_count is prompts and replies only: Claude, Cline and Roo stop counting tool results, OpenClaw sub-agent returns; OpenCode counts at cv index.

After upgrading, once.

  • source::VERSION is 7: listings rediscover once, so rc.1's cached Claude, Cline and OpenClaw counts are recounted.

Listing and counts.

  • A round-trip read (Demand::COMPLETE) never records counts: Hermes's rewound and superseded rows no longer inflate a session's count.

  • Unchanged Hermes and Devin subagent forests load from the catalog without copying or opening their source databases.

  • Cold SQLite snapshots stage beside the catalog, avoiding multi-gigabyte tmpfs copies; frozen or unwritable catalogs retain temporary staging.

  • Hermes scans delegate runs once per database state instead of once per parent during subagent indexing.

  • Claude fork inference reads each sibling's head once per file state, not once per session asking: a directory pass was quadratic.

  • Codex sub-agent forests parse the lane ledger once per ledger state, not once per parent.

  • Kimi Code discovery rescans only a new session, not every session, when the session index grows.

  • Kimi discovery rescans no session when kimi.json is rewritten; the cwd is applied after the scan cache.

  • OpenClaw parses its cron and sub-agent registries once per store state, not once per session.

  • Goose legacy .jsonl sessions are rescanned at discovery only when the file changes.

  • cv index reads compressed Codex rollouts in parallel, charging each its decoded size instead of the whole 2 GiB guard.

  • Claude sub-agent trees (show --tree, --subagents, lanes) reuse each unchanged agent's scan instead of rereading every transcript.

  • Codex forests and the edit guard walk the lane ledger through an index, not a scan of every row per parent.

  • A watch checkpoint or archive resume state of any size is kept; past 64 KiB or 1 MiB they were silently dropped.

  • One changed session rewrites its own catalog row, not its harness's every row; a refreshed harness keeps its place among cv ls ties.

  • cv show agent-…, workflow-name and ghost lookups read the catalog instead of rediscovering every Claude session on each call.

  • MCP observe_stream keeps every observed session's reader state in the server, not eight in the cursor, and reports rereads.

  • The sessions API resumes pages and heads for its 1024 most recent sessions of any size, not 32 under 256 KiB.

  • Codex rollouts over 8 MiB list the title and cwd a full read gives, not a head-and-tail sample; a grown rollout rescans only its appended records.

  • The prompt hook, task mutations, cv task list and GET /api/tasks resume from a stored fold of the task log, parsing only events appended since.

  • A sub-agent tree read saves its agent scans: a later show --tree, lanes or events --subagents rescans only changed agents.

  • A followed session with over 16 KiB of metadata no longer rereads to its end on every bounded watch read.

  • cv show --tree indents once per fork above a message, not per ancestor: a straight chain prints flat, linear in the session.

  • OpenClaw SQLite stores are rediscovered only when the store changes, not on every listing refresh.

  • A copied SQLite store with WAL frames is copied once per command, however large, not again whenever another database opens.

  • A Grok turn resumes from its mark instead of rereading the session; a new session in a cwd group no longer rereads its sub-agents.

  • A write to a Gemini or Qwen logs.json rereads only the sessions whose entries changed, and the file is parsed once per state.

  • A Kimi Code main-agent turn no longer rereads its sub-agents: each is certified by its own slice of state.json.

  • A write to the Cline SDK side databases rereads only the lead sessions whose schedule, cron or team rows changed.

  • Cline, Roo, Continue and OpenSession discovery rescan only files that changed; a Roo count reads ui_messages.json once; Continue sessions are certified by their index entry.

  • Reading every conversation of an export archive past the 8 MB roster cache scans it once, not once per conversation.

  • Zed, Cursor, Devin, Hermes and OpenClaw re-decode only sessions whose rows moved, and read each shared table or registry once per state.

  • Claude fork inference no longer mistakes a SessionStart hook's earlier timestamp for a copied head; only a copied first prompt or boundary counts.

  • Search staleness counts the preferred copy of each session, avoiding false drift from older duplicates.

  • cv search, /api/search and -q text: read what the index has not seen live, from its resume mark, within --live-bytes (256 MiB); --frozen reads none.

  • A write to a Hermes, Goose, OpenCode, Devin, Zed, Cursor or OpenClaw store rereads only the sessions whose rows changed.

  • cv index and the live search read only what was appended since the last index, not every session under 4 MiB of text whole.

  • An append to one Claude session no longer rereads the forks in its project directory; only a new or rewritten sibling does.

  • cv search without an index answers from that live read instead of exiting 1; --frozen without an index still names cv index.

  • cv stats --tokens keeps every live session's cached usage however large the store; it evicts only deleted sources, never re-reading the fleet.

Install clustervision 0.18.0-rc.2

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/emberian/cv/releases/download/v0.18.0-rc.2/clustervision-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/emberian/cv/releases/download/v0.18.0-rc.2/clustervision-installer.ps1 | iex"

Download clustervision 0.18.0-rc.2

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

0.18.0-rc.1 — 2026-10-22 — the release an agent can trust

Choose a tag to compare

@github-actions github-actions released this 22 Oct 16:34

Release Notes

Breaking: commands, MCP, HTTP and JSON. A removed name exits 2 with a pointer to its replacement; a changed shape is named here.

  • An uncounted session's message_count was 0; ls --json, /api/sessions and search rows now emit null.
  • cv archive ls counts turns like cv ls; catalog.jsonl rows keep the raw count as messages_written; 0.17's rows show a dash until resynced.
  • extra.openclaw keys copied from records keep native camelCase (stopReason, customType, error.errorCode); custom_details and branch_from_id become details and fromId.
  • An IR or OpenSession 0.3 message without kind or origin is refused instead of inferred from its role; cv has written both since 0.11.
  • Fidelity-report deltas elements and cv formats findings serialize as one Divergence, {what, a, b, expected, where}, replacing {field, before, after} and the old finding keys.
  • MCP tools generated from the CLI omit --follow (no Ctrl-C in a tool call); a follow argument is refused, naming for.
  • Installed hooks run cv hook <name> --harness <h>; $CV_HOOK_HARNESS exits 2 with a pointer to cv hooks install codex.
  • cv scry with stdout piped prints the sessions it would follow once and exits 0; --follow keeps following, --for 30s|5m|2h bounds it.
  • Watch and observe_stream cursors are version 2 (one mark per position); a 0.17 cursor starts a fresh baseline.
  • A tag-only decision (nothing posed, written before 0.15) reads as an assigned action, not a decision owed; the page's tagged-decision card is gone.
  • $CLAURDVOYANT_HOME and $CLAURDVOYANT_MAX_STALE_SECS exit 2 with a pointer to the CLUSTERVISION_ names; the claurdvoyant config, cache and home directories are no longer read.
  • cv rewind --from-compaction (the default start, never a switch) exits 2 with a pointer to --full.
  • cv deferrals --since <msg> is --at <msg> (--since is a duration on lanes); the old spelling exits 2 with a pointer.
  • cv dataset --out <path> is --file <path> (--out is a directory everywhere else); the old spelling exits 2 with a pointer.
  • cv tools --agent takes an exact id or unique prefix on every view, else exits 2; --across with --agent, --tool or --timeline exits 2.
  • An unknown cv task events --kind (or /api/events?kind=) exits 2 (400) naming the known kinds; it used to list nothing.
  • cv workflow exits 2 where it dropped flags: run-only flags with no run named, --revive-all without --revive, --revive with --json.
  • A -q with text: and no full-text index exits 2 naming cv index (/api/stats: 503) instead of matching nothing.
  • cv events, cv touched, cv blame and their HTTP routes fail on an event-catalog error instead of answering empty.

Breaking (library): cv-core, cv-search and cv-testkit APIs. Rust callers migrate as follows.

  • ParseOptions and ExtraProjection become Demand { tier, spans, offsets }; the five Watcher poll methods become poll/try_poll(Poll { .. }).
  • MessageSink::extra_projection is MessageSink::tier, returning a Tier; a sink that overrode it overrides tier.
  • Adapter::resume, try_resume and resume_format become Adapter::transcript(r, demand, Start, sink); append_only returns bool; JSONL transcripts share one driver.
  • Adapter::discover returns Discovered { refs, skipped }; an out-of-tree adapter returns Ok(refs.into()).
  • cline::discover_in returns Discovered; cline_sdk::discover takes &mut Discovered and fills it instead of returning refs.
  • Watcher::run is gone (callers own scheduling around poll); poll_sources is offer_sources.
  • Transcript text over 4 KiB is Text::Source (checked); Span is wire form only, a JSON string body; malformed escapes error instead of decoding lossily.
  • Unresolved Text formatting errors; matches_str replaces string equality, and is_lazy replaces is_span.
  • lazy::json_string_span is gone (adapters build Text::Source); try_resolve_prefix budgets decoded bytes, not raw (max_raw is max).
  • projection::Head replaces ir::Head: byte prefixes and character labels share one builder with separate budgets; push returns true once full.
  • projection::Counted is built with Counted::new; hashing() captures an optional SHA-256 digest during writes.
  • emit::Delta and formats::Finding become one emit::Divergence {what, a, b, expected, at} (at serializes as where); format-check returns follow.
  • formats::FindingKind::ManifestInvalid reports a manifest that does not parse, previously tagged source_file_missing.
  • SubagentInfo and claude::subagent_refs become ir::AgentRef and subagent_tree_of; claude::CARRIER_KEY is ir::CARRIER_KEY.
  • SubagentEnd, ApiErrorNotice and TaskNotice move from harness::claude to lanes.
  • Agent end, return, task-notice and workflow-launch reads return Result; aborted reads no longer imply missing or running agents.
  • Forest and subagent-reference APIs return Result; unreadable forests fail views, queries, indexing and stats instead of hiding agents.
  • one_agent_across returns Result<bool>: an unreadable forest is an error, not false.
  • Modules move: handoff is codex_handoff, loom is splice, harness::harmony is harness::wire::harmony.
  • wire::harmony::decode_content takes a call-id generator; derive position ids with ir::derived_call_id.
  • export::ChatGptExport, ClaudeExport and their with_roots are gone; use harness::for_harness_with_root(Harness::ChatGptExport, dir) (or ClaudeExport).
  • codex::parse_str, gemini::parse_all_str, parse_all_str_for and ingest::ingest_files return Result; a codec failure is an error, not a partial session.
  • store_affordances and json_files return Result; failed side-store reads now fail affordance views and count publication.
  • harness::wire::openai::tool_calls returns Result; an entry that fails to decode is an error, not a shorter list.
  • affordance::classify_tool is private and items_of/item_of are gone; use classify_tool_json/classify_tool_view and items_of_view/item_of_view.
  • affordance::Returns gains ResultInPrompt, the spawn-table row for Roo's new_task.
  • affordance::{unwrap,rewrap}_deferred take a DeferredWrapper, not a Harness; wire::anthropic's owned Texter/block_from*/blocks_from helpers are gone.
  • distill::distill splits into prepare_distill and distill_pack; Session::first_user_text and searchable_text are gone.
  • SearchRow::to_json is to_json_with(&SearchRowContext); scan::live_search is live_search_filtered; lazy::read_head is read_head_checked, returning Result.
  • Redaction and HTML message rendering require a resolver; Markdown consumers use write_md_message/write_md_block instead of removed buffering wrappers.
  • html::share_message_with_resolver is share_message(.., resolver); redact::scrub_value/scrub_cow are private: use redact_with, redact_message or redact_text.
  • RedactOptions.keep_emails is classes.emails, inverted: false keeps emails. task::AppendOutcome.replay_warnings (always empty) is gone.
  • source::Published becomes Record<T>; Table<T: Payload>, get returns a Record, admit replaces published/fresh; update is generic.
  • source::rename_consumer is gone: a consumer missing its baselines under a new identity rereads the source instead of migrating them.
  • catalog::fill_count is gone; a complete read certifies counts in the counts record.
  • resume::version returns String, not Option<String>; resume::MarkUpdate is a struct {session, mark}, not a tuple.
  • publish::retract is gone: a publish::Set owns grouped rollback. EmitOptions gains parsed_at, so exhaustive struct literals break.
  • EmitOptions.sidechain_of is Option<SidechainOf {root, agent}>; PruneOptions/RewindOptions gain skills_policy and their results skills, breaking exhaustive literals.
  • prune::prune_session takes the session's Harness first; prune and rewind accept a harness whose adapter declares derived copies.
  • events::ingest_all takes named IngestOptions instead of two positional booleans.
  • events::events_for, sessions_touching, sessions_editing and edits_touching_file return Result.
  • query::WindowPresence is gone: filter_refs_limited drops its presence argument and always skips absent sources before choosing the window.
  • lanes::Lane.status is a LaneStatus (Running, Stopped, Returned, Recorded(word); as_str and JSON unchanged); LaneEvent.event is LaneEventKind.
  • lanes::STRAND_PATTERNS is private: lanes::text_is_waiting is the strand check.
  • ForestTools::for_workflow is gone; tools::forest_tools_selected(r, None, Some(run_id), None) reads only that workflow.
  • query::HAS_FLAGS rows are (name, help, Cost) triples; destructuring code takes three fields.
  • task::store::append_agent_event (the free function) is gone; call TaskStore::default_store().append_agent_event(event).
  • Searcher::semantic is private; pass configured SemanticSearch state through Searcher::from.
  • cv-search's root text_search*, enrich_text_snippets, embed_all and semantic_search_filtered become Searcher::{search, search_in} and embed_sessions.
  • fts::enrich_text_snippets returns Result<Option<String>> (a degradation note). New fields (Stats.uncounted, HarnessCensus.first_error, LaneWork.unread) break exhaustive literals.
  • cv-testkit: heap::begin/end return a Measurement instead of a usize.
  • Env::enter_isolated returns Isolated(armed, Scope), which derefs to the scope, instead of a bare Scope.
  • cv-testkit: claude::user takes the session id first: user(sid, uuid, ts, text).

After upgrading, once.

  • The first listing rediscovers the fleet (announced on stderr; cv index does it ahead): a catalog stamped with another source::VERSION is dropped a...
Read more

0.17.0 — 2026-10-17 — stream, never materialize

Choose a tag to compare

@github-actions github-actions released this 17 Oct 21:29

Release Notes

cv's readers now stream: a giant tool output, a 60 MB escaped string or a 64 MiB SQLite cell
stays in its source file and is read through bounded windows, by one record codec per wire format.
cv index parses on every core and decodes compressed Codex rollouts with libzstd. Freshness is
verified on use, one record per consumer, over every primary source, sidecar and WAL, so a quiet
session's append is never missed. Search matches the exchange (what was asked, answered and run);
injected files, system prompts and hooks are --kind context. Untitled sessions are titled by
their first prompt. cv serve runs on a small built-in server. Measured on a frozen 5,421-session
fleet (Claude 38 GB, Codex 40 GB compressed, 89 GB decoded): a full index from an empty home takes
866 s at a 715 MB footprint, an unchanged index 0.4-0.8 s. No command is renamed or removed; the
table lists the flags, defaults, routes and MCP tool that changed.

old new
GET /api/backlog GET /api/tasks?detail=1 (the old route answers 410 with this pointer)
POST /api/task/{id}/reopen gone (410): a closed task stays closed; open a new task and note the old id
MCP hook gone; a call points at hooks_install (it read Claude Code's hook JSON on stdin, so a call did nothing)
cv search with no usable index scanned transcripts live an error naming the cause and the fix; cv search --scan (/api/search?scan=1) asks for the live scan
Codex plain rollouts over 8 MiB had extrapolated discovery counts message_count: 0 means not counted; compressed rollouts are counted in full; indexing supplies exact catalog counts
cv search matched injected files, system prompts and hooks matches the exchange; --kind context (/api/search?kind=context) for those, --kind all for both
/api/search?semantic=1&kind=context 400: vectors embed the exchange only
cv port --thinking native|text|drop, default native; cv rewind copied reasoning byte for byte --thinking portable on port, rewind, splice, pack; port and rewind default native when every recorded model is claude-*, else portable
prune --drop-thinking left an inline marker per flattened block omits the block; cv cat <new-id> <record-uuid>#think<i> returns it from the sidecar
prune --to <taken id>; dataset, pack, share, distill --pack onto an existing name wrote into it exit 2, nothing written; --force (prune, dataset, pack, share, distill) replaces by atomic rename
rewind --to and adopt refused a taken target with exit 1 exit 2; adopt --force still replaces; rewind requires another id
cv index exit 1 when any session was unreadable exit 0 with warnings when some sessions succeed; all unreadable still fails; --strict fails on any; --json lists unreadable
cv index --semantic --subagents a usage error before anything is written: run the two separately
a pre-binary embeddings.json semantic store not read or migrated; cv index --semantic rebuilds

cv tree, cv prompts, cv compaction, cv timeline, cv board and the other 0.15 names still
exit 2 with their pointers; the cvd and cv-mcp shims went in 0.16.0.

  • Reject premature EOF in positioned JSONL reads instead of treating missing captured bytes as a partial final record.
  • Preserve concurrent directory claims during fallback publication and restoration; retain both trees when restoration is blocked.

What reads differently (--json consumers):

  • Codex message_count counts logical turns, as the parser does: no duplicated event
    echoes, injected instructions or inherited history. OpenCode, Goose, Hermes, Devin and Qwen
    discovery counts match their parsers too; cached counts refresh once. Plain Codex rollouts over
    8 MiB report 0 until counted, replacing the old extrapolation.
  • An untitled session's title is its first exchange prompt, in index and scan hits, labels,
    Markdown, share and archive, never an injected AGENTS.md or environment turn; ls --json --enrich
    display_title prefers the row's title.
  • Search hits match the exchange. Injected instructions, system prompts, skill bodies, hook
    output, notices and compaction summaries match only with --kind context (or all); a fork's
    copied turns hit their source once; snippets keep the original Unicode. Every indexed answer, hit
    or miss, says how many sessions the index trails and by how long: stderr under --json, the
    X-Cv-Search-Note header on /api/search.
  • Claude rewind and port default to native when every recorded model is claude-*, else
    portable: plaintext thinking demoted to text, signature-only reasoning removed (no placeholder),
    illegal tool IDs mapped collision-free at both ends. rewind reports which. --thinking native
    writes what 0.16 wrote.
  • prune --drop-thinking omits old thinking blocks with no inline marker, removing emptied records
    and relinking their children; cv cat <new-id> <record-uuid>#think<i> still retrieves each.
  • cv doctor and prune separate byte estimates from recorded prompt usage and rewritten resume
    metadata; opaque thinking no longer counts as measured reasoning tokens. One estimator with
    per-kind rates calibrated against count_tokens replaces 3.5 bytes/token; prune's revive estimate
    anchors on recorded usage and never read more than 1% low against the API. Human labels change;
    --json keys do not.
  • Session JSON (show --json, /api/session/…/head, OpenSession) may carry a top-level
    principal, a string or an object, absent when unset; a splice keeps it only when every source
    agrees (#4).
  • Generated MCP tools return a successful command's stderr (continuation hints such as
    task_events's next: --since) as a second content block. Read content[0]; do not concatenate.
  • -q: a|b is OR and field="x" exact metadata equality; text equality errors naming the syntax
    to use. A harness-qualified id (claude:abc) discovers only that harness on a catalog miss; id
    prefixes stay case-sensitive.
  • cv serve answers 400 to malformed numeric parameters (/api/sessions?limit=abc was ignored),
    framing, headers and authorities. Task POSTs reject invalid JSON (400), oversized bodies (413),
    and a non-JSON media type or forbidden origin (403).
    GET /api/session/{harness}/{id}/export downloads the complete session as Markdown or OpenSession.
  • ls --json --limit 0 prints [] after argument validation without touching the inventory;
    cv index --json prints {indexed, path, unreadable: [{id, harness, reason}]}.
  • cv dataset keeps a session-level system prompt without duplicating explicit system messages.
    cv port --harness opencode writes OpenCode 2.x rows and can bootstrap a fresh store; 1.x stores
    still read.
  • Claude checkpoint counts keep restorable results, so has:checkpoint can change after the
    recount. Cursor Agent CLI chat and ACP stores appear as sessions.

One-time costs after upgrading (docs/design/PERF.md, 2026-10-14, release builds; frozen: an
APFS clone of 5,421 sessions, Claude 38 GB, Codex 40 GB compressed; live: ~7,000 sessions):

  • Run cv index first. The full-text index rebuilds once for the exchange/context split, the
    title rule and per-session metadata guards; afterwards a grown transcript is read from where the
    last pass stopped. A full build from an empty home: 866 s at a 715 MB footprint frozen; 966 s,
    RSS 3.4 GB live. Unchanged afterwards: 0.4-0.8 s frozen, 1.0-1.6 s live.
  • The first fleet read rediscovers every harness (the catalog's interpretation version changed) and
    may print a stderr note suggesting cv index when the old catalog records its interpretation
    version: cv ls, first run, frozen, 158-186 s. Do not pay it inside an agent's MCP call.
  • Indexing refreshes counts, events and search baselines together; usage refreshes on its first
    token-statistics read. Affordance counts (has:) are recounted (Claude checkpoints, OpenCode
    turns); watch cursors record file identities on their next pass.
  • cv search --semantic needs cv index --semantic once more: vectors embed the exchange only and
    a pre-binary embeddings.json store is no longer read (not measured).
  • The task log needs no migration. The catalog upgrades automatically: legacy counts and watch
    tables are recreated, cache columns added and discovery invalidated. No manual migration command
    is needed. Moving a home preserves its index when transcript paths and identities stay valid.

All changes

Reading

  • Schema includes hook_ledger among lane status sources and documents returned lanes; runtime lane JSON is unchanged.
  • Cursor Agent CLI chat and ACP blob stores are read: prompts, replies, tool calls, summaries, modes and lineage; numeric modes read as names.
  • Untitled sessions are titled by their first prompt everywhere (index and scan hits, labels, Markdown, share, archive), never injected AGENTS.md or environment context.
  • ls --json --enrich display_title uses the row's title when present and never picks harness-injected turns such as Codex AGENTS.md instructions.
  • Codex discovery counts logical turns as parsing does, excluding event echoes, injected instructions and inherited history; OpenCode, Goose, Hermes, Devin and Qwen likewise.
  • OpenCode: custom database names are discovered, WAL changes noticed, conflicting native ids refused; non-UTF-8-JSON message and part cells are skipped, not fatal.
  • OpenClaw: an empty event_json row is skipped; exports keep native records, branch links, compaction metadata and grouped tool results; escaped branch controls are recognized.
  • Gemini accepts escaped wrapper metadata and keeps saved-chat message classification; checkpoint replay and composite tool results read with bounded memory.
  • Kimi deferred wire outputs keep their source identity and reject replaced files; Ki...
Read more

0.16.1 — 2026-10-12 — approvals, checkpoints, and the side files

Choose a tag to compare

@github-actions github-actions released this 12 Oct 10:04

Release Notes

Two new affordance kinds, approval (asks, denials, the approval mode in force) and checkpoint
(restorable points, tallies, restores), and the side files 0.16.0 named as unread: Qwen schedules,
Cline schedule fires and team runs, OpenClaw cron and sub-agent registries, Kimi todos, Grok hook
runs; Claude --fork-session and Goose forks now name their source. Catalog counts carry a view
version, so has: recounts after an upgrade instead of answering from 0.16.0's counts: run
cv index once.

  • New affordance kinds approval (asks, denials, the session's approval mode) and checkpoint (restorable points, restores) in show --kind and has:.
  • Roo ui_messages.json checkpoints and permission asks, and Grok rewind_points.jsonl, are now read.
  • Session JSON gains permission_modes and checkpoints in the harness bag (Claude, Codex, Kimi, Kimi Code, Qwen, Gemini saved chats).
  • Devin edit results carry details.restorable, the files /revert can restore.
  • Catalog affordance counts from 0.16.0 are recounted on the next full read, so has:approval / has:checkpoint never answer from stale counts.
  • Side stores read: Qwen scheduled_tasks.json, OpenClaw cron and sub-agent registries, Cline schedule runs and teams.db, Kimi state.json todos, Grok hook runs.
  • Catalog affordance counts are recounted once more, to include these side stores and forks.
  • Claude --fork-session and Goose --fork sessions name their source in lineage.forked_from, inferred from the records the fork copied.

Install clustervision 0.16.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/emberian/cv/releases/download/v0.16.1/clustervision-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/emberian/cv/releases/download/v0.16.1/clustervision-installer.ps1 | iex"

Download clustervision 0.16.1

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

0.16.0 — 2026-10-12 — every harness, every version, every affordance

Choose a tag to compare

@github-actions github-actions released this 12 Oct 08:26

Release Notes

cv now carries a corpus of real sessions written by 17 harnesses at the versions in use and their
latest releases, re-read by a golden test, so a format change shows up as a test diff and old
formats keep reading. Building it found sessions cv could not see at all (OpenCode 2.x, Qwen Code
0.25, the Cline CLI store) and data it silently dropped (OpenClaw 10's compressed events, kimi-cli's
rotated segments, Grok reasoning). On top of it, one vocabulary for what swarms run on: plans,
goals, schedules, background jobs, sub-agent spawns and returns, skills, hooks, questions, branches,
forks and model changes, queried the same way on every harness with cv show --kind <affordance>
and -q has:<affordance>.

What reads differently: turns that spawn a sub-agent are subagent_spawn (and synchronous
results subagent_return) where they were reply/tool_result; Claude task-notifications and
interrupt/meta rows are no longer prompt; Hermes and OpenClaw tool_call wrappers read as the
tool they call. --json consumers keying on those kinds should update.

Run cv index once after upgrading: it counts every session's affordances so has: answers
from the catalog (minutes on a large fleet, incremental after).

All changes

  • The cvd and cv-mcp shims are gone, as 0.15 announced: cv archive|watch|serve and cv mcp. A launchd job or MCP registration that names them needs the new spelling.

  • has:plan and the other affordance flags answer from per-session counts in the catalog (filled by cv index and any full read); only uncounted sessions are parsed.

  • cv tools --timeline shows each call's tool_use_id (in --json too), the id cv cat <session> <id> takes.

  • cv tools --timeline shows one line per tool call, matching cv tools counts; a multi-file patch's other files are in more_targets.

  • cv port --harness qwen writes Qwen Code 0.25 session JSONL under ~/.qwen/projects; it wrote the gemini-cli shape 0.25 no longer reads.

  • cv show <id> --kind plan,schedule,background_job,… (affordances for all) lists plans, goals, schedules, jobs, spawns, skills, hooks and forks across harnesses, side stores included.

  • -q has:plan, has:schedule, has:background_job, …: select sessions by affordance on any harness (cv ls, MCP, cv serve).

  • Turns that spawn a sub-agent are subagent_spawn, and synchronous results subagent_return, in Claude, OpenCode, Hermes, OpenClaw, Goose, Grok, Kimi, Roo, Cline, Devin, Continue.

  • Claude: task-notifications are subagent_return (agents, workflows) or injected_context (commands); interrupt markers and isMeta rows are injected_context, not prompt.

  • Hermes and OpenClaw 10.1: a tool_call reads as the tool it calls, namespace tool_call; their emitters wrap it back.

  • Side stores read: Claude tasks/, Grok plan.json, OpenCode todo, Gemini tracker/ and plans/, Goose's todo extension, Hermes goals, loops and heartbeats.

  • A reply that spawns a sub-agent counts as a turn and stays in dataset, distill and lane message counts.

  • The compact hook names the command that reads back the session's plan, schedules and background jobs.

  • Qwen Code 0.25: sessions in ~/.qwen/projects/*/chats/*.jsonl and their sub-agent transcripts are read; cv previously found none.

  • Gemini: tool results and thoughts no longer appear twice after a resume, and a resumed 0.46 session is no longer hidden by its empty twin.

  • Gemini: hook context is its own turn; invoke_agent calls are sub-agent spawns and returns.

  • Gemini and Qwen corpus: real stores from Gemini CLI 0.46.0 and 0.63.0 and Qwen Code 0.25.1 in the golden test.

  • Codex 0.161/0.162: turn_aborted notes keep the abort error and root_turn_id; cv formats names carried records event_msg.<type> as the manifest does.

  • Codex corpus: real rollouts from Codex 0.161.0 and 0.162.1, re-read by a golden test so every recorded format keeps reading.

  • cv index merges its segments itself, by size, to completion: no more abandoned ~1 GB background merge on long runs.

  • cv show --last N and cv export --last N read the session once instead of counting it first: about half the time.

  • Kimi discovery reuses the scan cache: an unchanged transcript costs a stat, not a full read.

  • A follower of a Codex session holds only the new messages, not the whole parsed rollout (595 MB to 124 MB on a 708 MB rollout).

  • A cv search miss checks index staleness against the catalog instead of rescanning every harness: 0.53 s to 0.21 s.

  • cv ls --enrich keeps only each session's user turns while reading it: 720 MB to 80 MB peak on the largest sessions.

  • cv cat stops reading at the tool call it prints instead of holding the whole session.

  • OpenCode 2.x: sessions in its new session_v2/session_message tables are read (2.x databases looked empty before); a migrated 1.x database shows each session once.

  • OpenCode corpus: real stores from 1.18.20 and 2.0.25, plus 2.0.25's migration of the 1.18.20 store.

  • kimi-cli: sessions read every context_N.jsonl segment, not just the live file; /clear is a branch; subagents/ parse as child sessions.

  • Kimi Code 2.x: subagent.spawned/completed are spawn/return turns, /undo is a branch, kimi fork sets lineage.forked_from.

  • Kimi corpus: real stores from kimi-cli 1.48.0/1.51.0, Kimi Code 0.39.1/2.1.1, and a 0.39.1 store reopened by 2.1.1.

  • Cline: sessions from the CLI 3.x and the 4.x extension (~/.cline/data/sessions/) are read, including spawned sub-agents and teammates.

  • Roo: Roo CLI tasks (~/.vscode-mock/global-storage/tasks/) are found; reasoning blocks, condense summaries and new_task parents are read.

  • Continue: the cn CLI's tool results (toolCallStates) and per-turn usage and model are read; they were missing.

  • Devin: a run_subagent child, which has no subagent_heads row, is listed as its own session.

  • Corpora for Cline 3.0.70, Roo CLI 0.1.17, Continue cn 1.5.47 and Devin 3000.11.3; schema snapshots for Zed 1.16.1 and LM Studio 0.4.21.

  • Claude Code 2.1.296: ScheduleWakeup turns read as origin: scheduler; its corpus (18 sessions, 6 sub-agents, a workflow) joins the golden test.

  • Grok 1.0.50: reasoning records read as thinking; forks and sub-agents carry their parent; its corpus joins the golden test.

  • Goose: a real compaction (agent-visibility flip plus agent-only summary) reads as a compaction boundary; delegate results keep the child session id.

  • Goose corpus: real stores from Goose 1.51.0 and 1.54.0, covering every persisted affordance a headless run can drive.

  • OpenClaw 2026.10: zstd-compressed transcript events are read; before, every event of 1 KiB or more (most tool results) was silently dropped.

  • OpenClaw: sub-agent sessions name their parent (lineage.parent); cron and sub-agent prompts get scheduler/subagent origin; sub-agent announces are subagent_return.

  • OpenClaw corpus: real stores from 2026.1.29 (JSONL) and 2026.10.1 (sqlite), re-read by the golden test.

  • Hermes 0.21: a failed_turn row (a turn that got no reply) reads as an error; v29–v31 identity and source columns ride in extra.hermes.

  • Hermes corpus: real state.db stores from Hermes 2026.8.31 and 0.21.6, re-read by the golden test.

Install clustervision 0.16.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/emberian/cv/releases/download/v0.16.0/clustervision-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/emberian/cv/releases/download/v0.16.0/clustervision-installer.ps1 | iex"

Download clustervision 0.16.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

0.15.1 — 2026-10-11

Choose a tag to compare

@github-actions github-actions released this 11 Oct 11:05

Release Notes

  • The clustervision crate packages: the cv skill file lives inside the crate, so cargo install clustervision builds (0.15.0's CLI crate never reached crates.io).
  • CI packages every publishable crate on each push, so a file the published tarball lacks fails before a tag.

clustervision 0.15.1

Install clustervision 0.15.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/emberian/cv/releases/download/v0.15.1/clustervision-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/emberian/cv/releases/download/v0.15.1/clustervision-installer.ps1 | iex"

Download clustervision 0.15.1

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

cv-mcp 0.15.1

Install cv-mcp 0.15.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/emberian/cv/releases/download/v0.15.1/cv-mcp-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/emberian/cv/releases/download/v0.15.1/cv-mcp-installer.ps1 | iex"

Download cv-mcp 0.15.1

File Platform Checksum
cv-mcp-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
cv-mcp-x86_64-apple-darwin.tar.xz Intel macOS checksum
cv-mcp-i686-pc-windows-msvc.zip x86 Windows checksum
cv-mcp-x86_64-pc-windows-msvc.zip x64 Windows checksum
cv-mcp-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
cv-mcp-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
cv-mcp-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

cvd 0.15.1

Install cvd 0.15.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/emberian/cv/releases/download/v0.15.1/cvd-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/emberian/cv/releases/download/v0.15.1/cvd-installer.ps1 | iex"

Download cvd 0.15.1

File Platform Checksum
cvd-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
cvd-x86_64-apple-darwin.tar.xz Intel macOS checksum
cvd-i686-pc-windows-msvc.zip x86 Windows checksum
cvd-x86_64-pc-windows-msvc.zip x64 Windows checksum
cvd-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
cvd-i686-unknown-linux-gnu.tar.xz x86 Linux checksum
cvd-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum