Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
## [Unreleased]

### Added
- **`--hidden` flag**: Include hidden (dot-prefixed) files and directories in indexing and search operations
- **VitePress documentation site**: Comprehensive documentation with improved navigation, search, and structure in `docs-site/` directory
- **Documentation features**: Guide pages, feature documentation, CLI reference, embedding model guide, architecture docs, and contributing guides
- **Local search**: Built-in search functionality in documentation site
Expand Down
6 changes: 6 additions & 0 deletions ck-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ struct Cli {
#[arg(long = "no-ckignore", help = "Don't respect .ckignore file")]
no_ckignore: bool,

#[arg(long = "hidden", help = "Include hidden (dot-prefixed) files and directories")]
hidden: bool,

#[arg(
long = "print-default-ckignore",
help = "Print the default .ckignore content that ck generates and exit"
Expand Down Expand Up @@ -631,6 +634,7 @@ async fn run_index_workflow(
respect_gitignore: !cli.no_ignore,
use_ckignore: !cli.no_ckignore,
exclude_patterns: exclude_patterns.clone(),
show_hidden: cli.hidden,
};
let index_future = ck_index::smart_update_index_with_detailed_progress(
path,
Expand Down Expand Up @@ -1078,6 +1082,7 @@ async fn run_cli_mode(cli: Cli) -> Result<()> {
respect_gitignore: !cli.no_ignore,
use_ckignore: !cli.no_ckignore,
exclude_patterns: exclude_patterns.clone(),
show_hidden: cli.hidden,
};
let cleanup_stats = ck_index::cleanup_index(&clean_path, &file_options)?;
status.finish_progress(cleanup_spinner, "Cleanup complete");
Expand Down Expand Up @@ -1466,6 +1471,7 @@ fn build_options(cli: &Cli, reindex: bool, _repo_root: Option<&Path>) -> SearchO
respect_gitignore: !cli.no_ignore,
use_ckignore: !cli.no_ckignore,
full_section: cli.full_section,
hidden: cli.hidden,
// Enhanced embedding options (search-time only)
rerank: cli.rerank,
rerank_model: cli.rerank_model.clone(),
Expand Down
1 change: 1 addition & 0 deletions ck-cli/src/mcp/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ impl McpContext {
respect_gitignore: true,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: false,
rerank_model: None,
embedding_model: None,
Expand Down
1 change: 1 addition & 0 deletions ck-cli/src/mcp/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ mod tests {
respect_gitignore: true,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: false,
rerank_model: None,
embedding_model: None,
Expand Down
5 changes: 5 additions & 0 deletions ck-cli/src/mcp_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,7 @@ impl CkMcpServer {
respect_gitignore,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: request.rerank.unwrap_or(false),
rerank_model: request.rerank_model.clone(),
embedding_model: None,
Expand Down Expand Up @@ -1295,6 +1296,7 @@ impl CkMcpServer {
respect_gitignore,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: false,
rerank_model: None,
embedding_model: None,
Expand Down Expand Up @@ -1430,6 +1432,7 @@ impl CkMcpServer {
respect_gitignore,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: false,
rerank_model: None,
embedding_model: None,
Expand Down Expand Up @@ -1565,6 +1568,7 @@ impl CkMcpServer {
respect_gitignore,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: request.rerank.unwrap_or(false),
rerank_model: request.rerank_model.clone(),
embedding_model: None,
Expand Down Expand Up @@ -1820,6 +1824,7 @@ impl CkMcpServer {
respect_gitignore: true,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: false,
rerank_model: None,
embedding_model: None,
Expand Down
78 changes: 78 additions & 0 deletions ck-cli/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,3 +821,81 @@ fn test_add_file_with_relative_path() {
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Relative path content"));
}

#[test]
#[serial]
fn test_hidden_flag_includes_hidden_files() {
let temp_dir = TempDir::new().unwrap();

// Create a regular file
fs::write(temp_dir.path().join("visible.txt"), "visible content").unwrap();

// Create a hidden directory with a file inside
let hidden_dir = temp_dir.path().join(".hidden-test");
fs::create_dir(&hidden_dir).unwrap();
fs::write(hidden_dir.join("secret.txt"), "hidden secret content").unwrap();

// Create a hidden file at root level
fs::write(temp_dir.path().join(".hidden-file.txt"), "hidden file content").unwrap();

// First, index WITHOUT --hidden flag
let output = Command::new(ck_binary())
.args(["--index", "."])
.current_dir(temp_dir.path())
.output()
.expect("Failed to run ck --index");

assert!(output.status.success());

// Search for "hidden" - should NOT find the hidden files
let output = Command::new(ck_binary())
.args(["hidden", "."])
.current_dir(temp_dir.path())
.output()
.expect("Failed to run ck search");

let stdout = String::from_utf8(output.stdout).unwrap();
// Should not contain hidden directory content
assert!(
!stdout.contains("hidden secret content"),
"Hidden directory content should NOT be indexed without --hidden flag"
);
assert!(
!stdout.contains("hidden file content"),
"Hidden file content should NOT be indexed without --hidden flag"
);

// Clean the index
let _ = Command::new(ck_binary())
.args(["--clean", "."])
.current_dir(temp_dir.path())
.output()
.expect("Failed to run ck --clean");

// Now index WITH --hidden flag
let output = Command::new(ck_binary())
.args(["--hidden", "--index", "."])
.current_dir(temp_dir.path())
.output()
.expect("Failed to run ck --hidden --index");

assert!(output.status.success());

// Search for "hidden" WITH --hidden flag - should now find the hidden files
let output = Command::new(ck_binary())
.args(["--hidden", "hidden", "."])
.current_dir(temp_dir.path())
.output()
.expect("Failed to run ck search");

let stdout = String::from_utf8(output.stdout).unwrap();
// Should now contain hidden directory content
assert!(
stdout.contains("hidden secret content"),
"Hidden directory content should be indexed with --hidden flag"
);
assert!(
stdout.contains("hidden file content"),
"Hidden file content should be indexed with --hidden flag"
);
}
16 changes: 16 additions & 0 deletions ck-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,19 @@ pub struct FileCollectionOptions {
pub use_ckignore: bool,
/// Patterns to exclude files/directories
pub exclude_patterns: Vec<String>,
/// Whether to include hidden (dot-prefixed) files and directories
pub show_hidden: bool,
}

impl Default for FileCollectionOptions {
fn default() -> Self {
Self {
respect_gitignore: true,
use_ckignore: true,
exclude_patterns: Vec::new(),
show_hidden: false,
}
}
}

impl From<&SearchOptions> for FileCollectionOptions {
Expand All @@ -306,6 +319,7 @@ impl From<&SearchOptions> for FileCollectionOptions {
respect_gitignore: opts.respect_gitignore,
use_ckignore: true, // Always use .ckignore for hierarchical ignore support
exclude_patterns: opts.exclude_patterns.clone(),
show_hidden: opts.hidden,
}
}
}
Expand Down Expand Up @@ -338,6 +352,7 @@ pub struct SearchOptions {
pub respect_gitignore: bool,
pub use_ckignore: bool,
pub full_section: bool,
pub hidden: bool,
// Enhanced embedding options (search-time only)
pub rerank: bool,
pub rerank_model: Option<String>,
Expand Down Expand Up @@ -395,6 +410,7 @@ impl Default for SearchOptions {
respect_gitignore: true,
use_ckignore: true,
full_section: false,
hidden: false,
// Enhanced embedding options (search-time only)
rerank: false,
rerank_model: None,
Expand Down
1 change: 1 addition & 0 deletions ck-engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ fn regex_search(options: &SearchOptions) -> Result<Vec<SearchResult>> {
respect_gitignore: options.respect_gitignore,
use_ckignore: true,
exclude_patterns: options.exclude_patterns.clone(),
show_hidden: options.hidden,
};
let collected = ck_index::collect_files(&options.path, &file_options)?;
filter_files_by_include(collected, &options.include_patterns)
Expand Down
6 changes: 4 additions & 2 deletions ck-index/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ pub fn collect_files(
.git_ignore(true)
.git_global(true)
.git_exclude(true)
.hidden(true);
.hidden(!options.show_hidden);

// Add .ckignore support (hierarchical, like .gitignore)
if options.use_ckignore {
Expand All @@ -213,7 +213,7 @@ pub fn collect_files(
let combined_overrides = build_overrides(path, &all_patterns)?;

let mut walker_builder = WalkBuilder::new(path);
walker_builder.git_ignore(false).hidden(true);
walker_builder.git_ignore(false).hidden(!options.show_hidden);

// Add .ckignore support even without gitignore
if options.use_ckignore {
Expand Down Expand Up @@ -1830,6 +1830,7 @@ mod tests {
respect_gitignore: true,
use_ckignore: true,
exclude_patterns: vec![],
show_hidden: false,
};

// First index
Expand Down Expand Up @@ -1892,6 +1893,7 @@ mod tests {
respect_gitignore: true,
use_ckignore: true,
exclude_patterns: vec![],
show_hidden: false,
};
let stats = cleanup_index(test_path, &file_options).unwrap();
assert_eq!(stats.orphaned_entries_removed, 1);
Expand Down
1 change: 1 addition & 0 deletions ck-tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ impl TuiApp {
respect_gitignore: true,
use_ckignore: true,
full_section: false,
hidden: false,
rerank: false,
rerank_model: None,
embedding_model: None,
Expand Down