sview
sview is a small Rust CLI for producing agent-friendly structure views of files.
It is not an editor, refactoring engine, or IDE protocol client. Its first job is to help coding agents understand where the important structures are before they decide which exact ranges to read or edit.
Why
Coding agents often work with only two primitive file operations:
- read text;
- apply patch.
That is enough for small files, but it becomes expensive and fragile for large source files, Markdown documents, config files, and generated-looking artifacts. The agent has to repeatedly read broad ranges, remember where symbols or sections are, and produce large text patches without a compact structural map.
sview fills the gap before editing:
agent -> sview -> compact structure view -> targeted reads / patches
Swift and Objective-C output follows the same range-oriented outline:
tests/fixtures/swift_sample.swift (swift)
├─ import Foundation L1-1 — import Foundation
├─ struct Client L3-13 — struct Client {
│ ├─ property title L4-4 — let title: String
│ ├─ initializer init L6-8 — init(title: String) {
│ └─ function fetch L10-12 — func fetch(id: String) -> String {
├─ protocol Screen L15-18 — protocol Screen {
├─ extension Client L20-22 — extension Client {
└─ enum Mode L24-27 — enum Mode {
C/C++, Java/Kotlin, Swift, and Objective-C source output use the same contract for imports/includes/packages, namespaces/classes/types, fields/properties, constructors/initializers, functions, and methods:
src/client.cpp (cpp)
├─ include <string> L1-1 — #include <string>
└─ namespace demo L3-18 — namespace demo {
├─ class Client L4-11 — class Client {
│ ├─ method Client L6-6 — Client() = default;
│ ├─ method fetch L7-7 — void fetch(int id);
│ └─ field name_ L10-10 — std::string name_;
└─ function add L17-17 — int add(int a, int b) { return a + b; }
Kotlin/Android source views include packages, imports, classes, interfaces, objects, constructors, properties, and functions:
app/src/main/java/com/example/MainActivity.kt (kotlin)
├─ package com.example.app L1-1 — package com.example.app
├─ import android.app.Activity L3-3 — import android.app.Activity
└─ class MainActivity L18-28 — class MainActivity private constructor(
├─ constructor MainActivity L18-20 — class MainActivity private constructor(
├─ property title L21-21 — var title: String = "Home"
└─ function onCreate L25-27 — override fun onCreate() {
Project status
Status: 0.1.x released CLI.
The current crate provides a working Rust CLI with Markdown, Rust, C, C++, Java, Kotlin, Swift, Objective-C, JavaScript, and TypeScript structure views. Rust, C/C++, Java, Kotlin, Swift, Objective-C, and JS/TS parsing use tree-sitter grammars; Markdown parsing is still a lightweight line-oriented outline.
Installation
Install the latest release with Homebrew on macOS:
Or download a prebuilt binary from GitHub Releases:
|
Use sview-darwin-amd64.tar.gz or sview-darwin-arm64.tar.gz on macOS.
You can also install the released CLI from crates.io:
Or install from the repository checkout:
Design goals
- Agent-facing: optimize output for downstream agents, not for human IDE UI.
- View first: inspect and summarize structure; do not mutate files.
- Fast local CLI: start quickly, work well in shell-based agent runtimes, and produce bounded output.
- Stable ranges: report line ranges that can guide follow-up
sed, editor, patch, or tool calls. - Broad file coverage: support code, Markdown, configuration, scripts, and other structured text files over time.
- Machine-readable by default: provide a stable JSON contract, with optional text formats for humans and agents.
- Small core: avoid becoming a full LSP client, IDE backend, or rewrite framework in the first phase.
Non-goals
First versions should not implement:
- rename symbol;
- move symbol / move module;
- extract function / extract module;
- organize imports;
- compiler or LSP diagnostics;
- code actions;
- automatic rewrites.
Those capabilities may later belong in a sibling tool such as sedit, or in a higher-level agent harness that combines sview with parser, LSP, compiler, or codemod backends.
CLI
The CLI is shaped around simple file-oriented calls:
The 0.1.x CLI supports:
- one or more input files per invocation;
- automatic language detection from path and content;
- JSON output;
- optional compact text output;
- maximum depth / maximum nodes / maximum preview length controls.
Output model
A structure view is a tree of nodes with source ranges:
For Markdown, the same contract can represent headings and document regions:
The output should be deliberately boring: stable keys, predictable ranges, and enough preview text to help an agent choose the next read or edit range.
First implementation slice
A useful MVP can stay very small:
- Markdown outline from headings, frontmatter, code blocks, and list regions.
- Rust outline for modules, structs, enums, traits, impl blocks, functions, and tests.
- JSON output with line ranges and short previews.
- Compact text output for quick terminal use.
- Real agent-assisted navigation inside tasks that currently require large-file inspection.
Agent navigation
Use sview as a navigation tool when structure can reduce uncertainty before
reading or editing. Agents should use it when a compact structure map is likely
to save broad reads, but should not force it into small files, direct text
lookups, or already-known edits.
Good triggers:
- an unfamiliar file may need to be read mostly end-to-end, especially if it is large enough that a structural map can avoid broad reads;
- the target symbol, section, test, or implementation area is only approximate and text search does not identify a tight range;
- several candidate Rust, C/C++, Java, Swift, Objective-C, JavaScript, TypeScript, or Markdown files or symbols need quick triage before choosing exact ranges;
- a patch changes parser-visible structure and the resulting outline should be checked.
Skip sview when the exact small range is already known, when rg directly
answers the question, when the file is small enough for one focused read, when
only one or two obvious candidate files are involved, or when the file type is
unsupported and an outline would not guide a better next read.
Typical commands:
Text output is a compact tree outline:
src/main.rs (rust)
├─ struct Cli L8-31 — struct Cli {
├─ enum OutputFormat L34-37 — enum OutputFormat {
└─ function main L39-54 — fn main() -> Result<()> {
TypeScript output uses the same shape:
tests/fixtures/typescript_sample.ts (typescript)
├─ interface User L1-3 — export interface User {
├─ type UserId L5-5 — type UserId = string;
├─ enum Mode L7-10 — enum Mode {
└─ class Service L12-16 — export class Service {
└─ method load L13-15 — async load(id: UserId): Promise<User> {
The intended workflow is:
- try the cheapest locator first: file names,
rg, or existing compiler/test output; - if that gives a precise file and line range, read that range directly and skip
sview; - if the target is still approximate, spans multiple candidates, or would require
broad reads, run
sviewwith a shallow--depth/--max-nodeslimit; - read only the relevant range with a focused command such as
sed -n '120,180p'; - patch or inspect the exact range, then rerun
sviewor tests if structure changed.
Possible implementation approach
Rust is the preferred implementation language because sview should behave like local developer tools such as rg, bat, or ast-grep:
- fast startup;
- single binary distribution;
- predictable file and range handling;
- good parser ecosystem;
- easy JSON output;
- suitable for repeated agent subprocess calls.
Current implementation dependencies:
clapfor CLI parsing;serde/serde_jsonfor output contracts;tree-sitter,tree-sitter-c,tree-sitter-cpp,tree-sitter-rust,tree-sitter-java,tree-sitter-swift,tree-sitter-objc,tree-sitter-javascript, andtree-sitter-typescriptfor code outlines.
Possible future dependencies include more tree-sitter grammars for additional languages and pulldown-cmark or another Markdown parser for richer document outlines.
Development and coverage
Run the normal verification before submitting changes:
Coverage is tracked with cargo-llvm-cov:
cargo coverage is a Cargo alias for cargo llvm-cov --workspace --all-targets --summary-only.
Initial coverage target: keep the core library line coverage at 70% or higher while the project is small. Parser behavior should be covered with checked-in fixtures under tests/fixtures/ for every supported language.
Release
Release readiness checks:
The crate is licensed under Apache-2.0. Release tags use the vMAJOR.MINOR.PATCH form, for example v0.1.0.
Pushing a release tag runs the GitHub release workflow. It uploads Linux amd64,
macOS amd64, and macOS arm64 tarballs plus checksums.txt, and generates a
Homebrew formula for holon-run/homebrew-tap when the tap token is configured.
Relationship to other tools
sview is narrower than an IDE and higher-level than raw parser output:
agent -> sview -> tree-sitter / markdown parser / ast-grep / LSP / compiler
- LSP can be a backend later, but the agent should not need to speak LSP directly.
ast-grepcan be a backend for structural matching or future rewrite workflows, butsviewshould first expose an outline, not a grep interface.- IDE MCP servers and tools like Serena are closer to full code intelligence backends;
sviewstarts as a lightweight CLI surface.
Repository layout
.
├── README.md
├── Cargo.toml
├── LICENSE
├── .github/
│ └── workflows/
│ └── ci.yml
├── src/
│ ├── analyzer.rs
│ ├── javascript.rs
│ ├── markdown.rs
│ ├── model.rs
│ ├── render.rs
│ ├── rust.rs
│ ├── util.rs
│ ├── lib.rs
│ └── main.rs
├── skills/
│ └── sview/
└── tests/
└── fixtures/