Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b5bbae8
docs(skills): refine release notes tone guidelines to favor clarity o…
tusharmath Apr 13, 2026
07d265e
feat(completer): replace nucleo fuzzy matcher with fzf-based file pic…
tusharmath Apr 13, 2026
d8ff325
feat(cli): add `list file` command and migrate shell plugin file list…
tusharmath Apr 13, 2026
67af95b
feat(completer): replace command completion list with fzf-based picker
tusharmath Apr 13, 2026
393624a
feat(highlighter): add syntax highlighter for slash commands, shell c…
tusharmath Apr 13, 2026
ef20df4
feat(repl): add colon prefix support and redesign starship-themed prompt
tusharmath Apr 13, 2026
c31c1a4
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 13, 2026
ec6d800
fix(prompt): dim model label when prompt is inactive and improve inva…
tusharmath Apr 13, 2026
fa8bb7a
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 13, 2026
7b4a40a
Merge branch 'main' into fzf-repl-tagging
tusharmath Apr 13, 2026
477061b
chore(config): remove unused fd command detection
tusharmath Apr 13, 2026
4a23e70
fix(prompt): replace hardcoded ANSI color indices with named color co…
tusharmath Apr 13, 2026
471d289
refactor(repl): migrate slash commands from json file to enum-driven …
tusharmath Apr 13, 2026
23a33a0
refactor(shell-plugin): remove doctor and keyboard-shortcuts commands…
tusharmath Apr 13, 2026
c645dec
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 13, 2026
47aee9a
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Apr 13, 2026
c5cf49e
fix(highlighter): apply mention highlighting to text after slash comm…
tusharmath Apr 13, 2026
12fd97b
refactor(prompt): remove starship references from comments
tusharmath Apr 13, 2026
96779a2
refactor(repl): rename SlashCommand to AppCommand and migrate parser …
tusharmath Apr 13, 2026
c7938c7
fix(repl): remove colon prefix from fzf tag buffer pre-fill
tusharmath Apr 13, 2026
e5f367c
fix(repl): output commit result directly instead of setting buffer co…
tusharmath Apr 13, 2026
996ef46
feat(repl): add optional conversation id arg to switch conversations …
tusharmath Apr 13, 2026
b71bd9d
fix(repl): change conversation id arg from vec to option
tusharmath Apr 13, 2026
b251e36
fix(repl): show accumulated session cost instead of last request cost…
tusharmath Apr 13, 2026
b2eee90
Merge branch 'main' into fzf-repl-tagging
tusharmath Apr 13, 2026
30398aa
[autofix.ci] apply automated fixes
autofix-ci[bot] Apr 13, 2026
40b218c
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Apr 13, 2026
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 crates/forge_infra/src/fs_read_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl ForgeDirectoryReaderService {
.cwd(directory.to_path_buf())
.max_depth(1)
.skip_binary(true)
.hidden(true)
.get()
.await?;

Expand Down
3 changes: 2 additions & 1 deletion crates/forge_infra/src/walker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ impl ForgeWalkerService {
&& config.max_files.is_none()
&& config.max_total_size.is_none()
{
forge_walker::Walker::max_all()
// Agent-facing walker: keep hidden files excluded by default.
forge_walker::Walker::max_all().hidden(true)
} else {
forge_walker::Walker::min_all()
};
Expand Down
1 change: 0 additions & 1 deletion crates/forge_main/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ lazy_static.workspace = true
reedline.workspace = true
crossterm = "0.29.0"
nu-ansi-term.workspace = true
nucleo.workspace = true
tracing.workspace = true
chrono.workspace = true
serde_json.workspace = true
Expand Down
16 changes: 8 additions & 8 deletions crates/forge_main/src/banner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ impl fmt::Display for DisplayBox {
///
/// # Arguments
///
/// * `cli_mode` - If true, shows CLI-relevant commands with `:` prefix. If
/// false, shows all interactive commands with `/` prefix.
/// * `cli_mode` - If true, shows CLI-relevant commands. Both interactive and
/// CLI modes use `:` as the canonical command prefix.
///
/// # Environment Variables
///
Expand Down Expand Up @@ -76,12 +76,12 @@ pub fn display(cli_mode: bool) -> io::Result<()> {
} else {
// Interactive mode: show all commands
vec![
("New conversation:", "/new"),
("Get started:", "/info, /usage, /help, /conversation"),
("Switch model:", "/model"),
("Switch agent:", "/forge or /muse or /agent"),
("Update:", "/update"),
("Quit:", "/exit or <CTRL+D>"),
("New conversation:", ":new"),
("Get started:", ":info, :usage, :help, :conversation"),
("Switch model:", ":model"),
("Switch agent:", ":forge or :muse or :agent"),
("Update:", ":update"),
("Quit:", ":exit or <CTRL+D>"),
]
};

Expand Down
142 changes: 0 additions & 142 deletions crates/forge_main/src/built_in_commands.json

This file was deleted.

7 changes: 7 additions & 0 deletions crates/forge_main/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ pub enum ListCommand {
#[arg(long)]
custom: bool,
},

/// List files and directories in the current workspace.
///
/// Includes hidden files and directories (dotfiles), respects .gitignore,
/// and outputs one path per line. Directories are suffixed with `/`.
#[command(alias = "files")]
File,
}

/// Shell extension commands.
Expand Down
78 changes: 60 additions & 18 deletions crates/forge_main/src/completer/command.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
use std::sync::Arc;

use forge_select::ForgeWidget;
use reedline::{Completer, Span, Suggestion};

use crate::model::ForgeCommandManager;
use crate::model::{ForgeCommand, ForgeCommandManager};

/// A display wrapper for `ForgeCommand` that renders the name and description
/// side-by-side for fzf.
#[derive(Clone)]
struct CommandRow(ForgeCommand);

impl std::fmt::Display for CommandRow {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:<30} {}", self.0.name, self.0.description)
}
}

#[derive(Clone)]
pub struct CommandCompleter(Arc<ForgeCommandManager>);
Expand All @@ -15,35 +27,65 @@ impl CommandCompleter {

impl Completer for CommandCompleter {
fn complete(&mut self, line: &str, _: usize) -> Vec<reedline::Suggestion> {
self.0
// Determine which sentinel the user typed (`:` or `/`), defaulting to `/`.
let sentinel = if line.starts_with(':') { ':' } else { '/' };

// Build the list of display names using the same sentinel the user typed.
let commands: Vec<CommandRow> = self
.0
.list()
.into_iter()
.filter_map(|cmd| {
// For command completion, we want to show commands with `/` prefix
let display_name = if cmd.name.starts_with('!') {
// Shell commands already have the `!` prefix
cmd.name.clone()
} else {
// Add `/` prefix for slash commands
format!("/{}", cmd.name)
format!("{}{}", sentinel, cmd.name)
};

// Check if the display name starts with what the user typed
// Only include commands that match what the user has typed so far.
if display_name.starts_with(line) {
Some(Suggestion {
value: display_name,
description: Some(cmd.description),
style: None,
extra: None,
span: Span::new(0, line.len()),
append_whitespace: false,
match_indices: None,
display_override: None,
})
Some(CommandRow(ForgeCommand {
name: display_name,
description: cmd.description,
value: cmd.value,
}))
} else {
None
}
})
.collect()
.collect();

if commands.is_empty() {
return vec![];
}

// Extract the initial query text (everything after the leading sentinel or
// `!`).
let initial_query = line
.strip_prefix('/')
.or_else(|| line.strip_prefix(':'))
.or_else(|| line.strip_prefix('!'))
.unwrap_or(line);

let mut builder = ForgeWidget::select("Command", commands);
if !initial_query.is_empty() {
builder = builder.with_initial_text(initial_query);
}

match builder.prompt() {
Ok(Some(row)) => {
vec![Suggestion {
value: row.0.name,
description: None,
style: None,
extra: None,
span: Span::new(0, line.len()),
append_whitespace: true,
match_indices: None,
display_override: None,
}]
}
_ => vec![],
}
}
}
Loading
Loading