Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ serde = "serde"
reqwest = "reqwest"
clippy = "clippy"
streamable = "streamable"
indicatif = "indicatif"
62 changes: 61 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "deepwiki-cli"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
description = "CLI for DeepWiki — query GitHub repo wikis without MCP overhead"
license = "MIT"
Expand All @@ -15,6 +15,7 @@ path = "src/main.rs"
[dependencies]
anyhow = "1.0"
clap = { version = "4", features = ["derive"] }
indicatif = "0.17"
rmcp = { version = "0.17", features = ["transport-streamable-http-client-reqwest", "client", "reqwest"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
13 changes: 13 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod cli;
mod client;
mod output;
mod spinner;

use anyhow::Result;
use clap::Parser;
use cli::{Cli, Command};
use client::DeepWikiClient;
use spinner::Spinner;

#[tokio::main]
async fn main() {
Expand All @@ -27,20 +29,31 @@ async fn run() -> Result<()> {
return Ok(());
}

let spinner = Spinner::start("Connecting to DeepWiki...");
let client = DeepWikiClient::connect().await?;

spinner.set_message(&command_spinner_message(&cli.command));
let text = match &cli.command {
Command::Ask { repo, question } => client.ask_question(repo, question).await?,
Command::Structure { repo } => client.read_wiki_structure(repo).await?,
Command::Read { repo } => client.read_wiki_contents(repo).await?,
};
spinner.finish();

println!("{}", output::format_for_claude(&text, repo, query_type));
client.cancel().await?;

Ok(())
}

fn command_spinner_message(command: &Command) -> String {
match command {
Command::Ask { repo, .. } => format!("Asking DeepWiki about {}...", repo),
Command::Structure { repo } => format!("Fetching wiki structure for {}...", repo),
Command::Read { repo } => format!("Reading wiki contents for {}...", repo),
}
}

fn repo_and_query_type(command: &Command) -> (&str, &str) {
match command {
Command::Ask { repo, .. } => (repo, "ask"),
Expand Down
56 changes: 56 additions & 0 deletions src/spinner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
use std::time::Duration;

const TICK_INTERVAL: Duration = Duration::from_millis(80);

pub struct Spinner {
bar: ProgressBar,
}

impl Spinner {
pub fn start(message: &str) -> Self {
let bar = ProgressBar::new_spinner();
bar.set_draw_target(ProgressDrawTarget::stderr());
bar.set_style(
ProgressStyle::default_spinner()
.tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
.template("{spinner} {msg}")
.expect("template should be valid"),
);
bar.set_message(message.to_string());
bar.enable_steady_tick(TICK_INTERVAL);
Self { bar }
}

pub fn set_message(&self, message: &str) {
self.bar.set_message(message.to_string());
}

pub fn finish(self) {
self.bar.finish_and_clear();
}
}

impl Drop for Spinner {
fn drop(&mut self) {
self.bar.finish_and_clear();
Comment thread
minsoo-web marked this conversation as resolved.
Outdated
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn spinner_starts_and_finishes_without_panic() {
let spinner = Spinner::start("test message");
spinner.set_message("updated message");
spinner.finish();
}

#[test]
fn spinner_drop_cleans_up() {
let spinner = Spinner::start("test message");
drop(spinner);
}
}
Loading