refactor: massive codebase restructuring — naming, splitting, DRY
Crate renames: - zesdex-entities::seaorm → domain (misleading name, no SeaORM used) - zesdex-dto → merged into zesdex-entities (100% re-exports) - zesdex-libs → zesdex-infra (vague name) Module renames: - app/harness → guard (misleading: safety gatekeeper, not test harness) - runtime/commands → action_dispatch (name clashed with controller/command) - resources → prompts (embedded prompt text, not general resources) - tool/seqthink → sequential_think (unreadable abbreviation) - msglog/query → insert (module only inserts, never queries) Dead code removal: - app/mode/help.rs (orphaned — not declared in mod.rs) - app/mode/loading.rs (orphaned — not declared in mod.rs) File splitting (71 new files, avg ~115 lines/file): - app/runtime/actions/: 1→8 files (was 2030 lines) - view/overlays/: 1→16 files (was 1167 lines) - tool/lsp/: 1→8 per-tool files (was 909 lines) - main.rs: 1→5 files (session, daemon, attach, event_loop) - workflow/engine + hive_mind: 2→10 files - subagent/engine + auto: 2→9 files - lsp/provisioner: 1→5 files - review/: 1→6 files - guard/: 1→2 files (extracted patterns) - state/misc: 1→3 files (input, scroll) - mcp/: 1→3 files (transport, adapter) - stream/json_repair extracted from turn.rs DRY: - Pattern constants (STUB_PATTERNS etc) in guard/patterns shared with subagent - 3 near-identical background spawners → 1 generic + thin wrappers - Shared spawn_subagent_with_drain() extracted - Shared create_session() in main - write_osc52 deduplicated Bug fixes: - archive_message(): sess.db → db (wrong variable name) - execute_one_tool(): wrong parameter name - check_credential_read() function was missing (restored from test expectations)
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
//! Path classification helpers for auto-subagent orchestration.
|
||||
//!
|
||||
//! Determines whether a file path is reviewable and whether it represents
|
||||
//! production code (vs. tests, config, or documentation) — used to decide
|
||||
//! which background subagents should fire for a given set of modified files.
|
||||
|
||||
/// File extensions that should not trigger auto-review (config, lock, data).
|
||||
pub(crate) const SKIP_REVIEW_EXTENSIONS: &[&str] = &[
|
||||
".lock",
|
||||
".md",
|
||||
".txt",
|
||||
".json",
|
||||
".toml",
|
||||
".yaml",
|
||||
".yml",
|
||||
".svg",
|
||||
".png",
|
||||
".jpg",
|
||||
".ico",
|
||||
".woff",
|
||||
".woff2",
|
||||
];
|
||||
|
||||
/// File names that should not trigger auto-review.
|
||||
pub(crate) const SKIP_REVIEW_FILES: &[&str] = &[
|
||||
"Cargo.lock",
|
||||
"yarn.lock",
|
||||
"package-lock.json",
|
||||
".gitignore",
|
||||
".env",
|
||||
".env.example",
|
||||
];
|
||||
|
||||
/// Check whether a file path is worth auto-reviewing (not config/lock/data).
|
||||
///
|
||||
/// Vendored/generated directories are matched by path *segment* rather than
|
||||
/// a `/target/`-style substring check — the substring form misses paths
|
||||
/// where the directory is the first component (e.g. `target/debug/build.rs`,
|
||||
/// which has no leading slash), the same class of bug fixed in
|
||||
/// `is_production_code` below.
|
||||
pub fn is_reviewable_path(path: &str) -> bool {
|
||||
let lower = path.to_lowercase();
|
||||
if SKIP_REVIEW_FILES.iter().any(|f| lower.ends_with(f)) {
|
||||
return false;
|
||||
}
|
||||
if SKIP_REVIEW_EXTENSIONS.iter().any(|e| lower.ends_with(e)) {
|
||||
return false;
|
||||
}
|
||||
// Skip paths that are clearly generated or vendored
|
||||
let in_vendored_dir = std::path::Path::new(&lower).components().any(|c| {
|
||||
matches!(
|
||||
c,
|
||||
std::path::Component::Normal(seg)
|
||||
if matches!(seg.to_str(), Some("target" | "node_modules" | ".git" | "vendor"))
|
||||
)
|
||||
});
|
||||
if in_vendored_dir {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Determine whether a file change looks like it modifies production logic
|
||||
/// (vs. tests, config, or documentation) — used to decide if a test-gen
|
||||
/// or security-review background subagent should fire.
|
||||
///
|
||||
/// Matches test-ness by path *segment* (a directory literally named
|
||||
/// "test"/"tests"/"__tests__") or by filename convention
|
||||
/// (`foo_test.rs`, `foo.test.ts`, `test_foo.py`, `foo_spec.rb`), not by a
|
||||
/// raw substring check — a plain `.contains("test")` would wrongly exclude
|
||||
/// legitimate production files like `src/attestation.rs` or
|
||||
/// `src/latest/foo.rs`.
|
||||
pub(crate) fn is_production_code(path: &str) -> bool {
|
||||
let lower = path.to_lowercase();
|
||||
let path_obj = std::path::Path::new(&lower);
|
||||
|
||||
let in_test_dir = path_obj.components().any(|c| {
|
||||
matches!(
|
||||
c,
|
||||
std::path::Component::Normal(seg)
|
||||
if matches!(seg.to_str(), Some("test" | "tests" | "__tests__"))
|
||||
)
|
||||
});
|
||||
|
||||
let file_stem = path_obj.file_stem().and_then(|s| s.to_str()).unwrap_or("");
|
||||
let is_test_filename = file_stem.starts_with("test_")
|
||||
|| file_stem.ends_with("_test")
|
||||
|| std::path::Path::new(file_stem)
|
||||
.extension()
|
||||
.is_some_and(|ext| ext.eq_ignore_ascii_case("test"))
|
||||
|| file_stem == "spec"
|
||||
|| file_stem.ends_with("_spec")
|
||||
|| std::path::Path::new(file_stem)
|
||||
.extension()
|
||||
.is_some_and(|ext| ext.eq_ignore_ascii_case("spec"));
|
||||
|
||||
if in_test_dir || is_test_filename {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only source files — use Path::extension() to avoid clippy
|
||||
// case_sensitive_file_extension_comparisons lint
|
||||
path_obj
|
||||
.extension()
|
||||
.and_then(|ext| ext.to_str())
|
||||
.is_some_and(|ext| {
|
||||
matches!(
|
||||
ext,
|
||||
"rs" | "ts"
|
||||
| "tsx"
|
||||
| "js"
|
||||
| "jsx"
|
||||
| "go"
|
||||
| "py"
|
||||
| "java"
|
||||
| "kt"
|
||||
| "swift"
|
||||
| "c"
|
||||
| "cpp"
|
||||
| "h"
|
||||
| "hpp"
|
||||
)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user