huskies: merge 858

This commit is contained in:
dave
2026-04-29 10:41:32 +00:00
parent be5db846cc
commit 11d111360d
79 changed files with 265 additions and 0 deletions
+1
View File
@@ -39,6 +39,7 @@ pub async fn write_file(path: String, content: String, state: &SessionState) ->
}
#[derive(Serialize, Debug, poem_openapi::Object)]
/// A directory listing entry with its name and kind (file or directory).
pub struct FileEntry {
pub name: String,
pub kind: String,
+5
View File
@@ -1,8 +1,13 @@
//! Filesystem I/O — module declarations and re-exports for file operations.
/// File read/write/list operations.
pub mod files;
/// Path resolution and project-root discovery.
pub mod paths;
/// User model-preference storage.
pub mod preferences;
/// Project open/close/list lifecycle.
pub mod project;
/// `.huskies/` directory scaffolding for new projects.
pub mod scaffold;
pub use files::{
+1
View File
@@ -29,6 +29,7 @@ pub fn find_story_kit_root(start: &Path) -> Option<PathBuf> {
}
}
/// Return the current user's home directory as a string.
pub fn get_home_directory() -> Result<String, String> {
let home = homedir::my_home()
.map_err(|e| format!("Failed to resolve home directory: {e}"))?
+2
View File
@@ -4,6 +4,7 @@ use serde_json::json;
const KEY_SELECTED_MODEL: &str = "selected_model";
/// Read the user's selected LLM model name from the store.
pub fn get_model_preference(store: &dyn StoreOps) -> Result<Option<String>, String> {
if let Some(model) = store
.get(KEY_SELECTED_MODEL)
@@ -15,6 +16,7 @@ pub fn get_model_preference(store: &dyn StoreOps) -> Result<Option<String>, Stri
Ok(None)
}
/// Persist the user's selected LLM model name to the store.
pub fn set_model_preference(model: String, store: &dyn StoreOps) -> Result<(), String> {
store.set(KEY_SELECTED_MODEL, json!(model));
store.save()?;
+4
View File
@@ -84,6 +84,7 @@ pub async fn open_project(
Ok(path)
}
/// Close the active project by clearing the in-memory root and stored path.
#[allow(dead_code)]
pub fn close_project(state: &SessionState, store: &dyn StoreOps) -> Result<(), String> {
{
@@ -99,6 +100,7 @@ pub fn close_project(state: &SessionState, store: &dyn StoreOps) -> Result<(), S
Ok(())
}
/// Return the active project path, restoring it from the store if needed.
#[allow(dead_code)]
pub fn get_current_project(
state: &SessionState,
@@ -133,6 +135,7 @@ pub fn get_current_project(
Ok(None)
}
/// List all previously-opened project paths from the store.
#[allow(dead_code)]
pub fn get_known_projects(store: &dyn StoreOps) -> Result<Vec<String>, String> {
let projects = store
@@ -146,6 +149,7 @@ pub fn get_known_projects(store: &dyn StoreOps) -> Result<Vec<String>, String> {
Ok(projects)
}
/// Remove a project path from the known-projects list in the store.
#[allow(dead_code)]
pub fn forget_known_project(path: String, store: &dyn StoreOps) -> Result<(), String> {
let mut known_projects = get_known_projects(store)?;
+7
View File
@@ -1,10 +1,17 @@
//! I/O subsystem — filesystem, shell, search, onboarding, and story metadata operations.
/// Filesystem helpers — file/directory read, write, list, path resolution, and project scaffolding.
pub mod fs;
/// Onboarding — guides new projects through spec setup and initial configuration.
pub mod onboarding;
/// Code search — full-text search across project files using the `ignore` crate.
pub mod search;
/// Shell command execution — runs sandboxed commands in the project directory.
pub mod shell;
/// Story metadata — parses and serialises front-matter from story files.
pub mod story_metadata;
#[cfg(test)]
pub(crate) mod test_helpers;
/// Filesystem watcher — detects config changes and pipeline file events for hot-reload.
pub mod watcher;
/// Project wizard — multi-step state machine for guided project initialisation.
pub mod wizard;
+1
View File
@@ -7,6 +7,7 @@ use std::fs;
use std::path::PathBuf;
#[derive(Serialize, Debug, poem_openapi::Object)]
/// A single file that matched a text search, with its match count.
pub struct SearchResult {
pub path: String,
pub matches: usize,
+1
View File
@@ -4,6 +4,7 @@ use serde::Serialize;
use std::path::PathBuf;
use std::process::Command;
/// Output captured from a shell command: stdout, stderr, and exit code.
#[derive(Serialize, Debug, poem_openapi::Object)]
pub struct CommandOutput {
pub stdout: String,
+3
View File
@@ -24,6 +24,7 @@ impl QaMode {
}
}
/// Return the lowercase string representation of this QA mode.
pub fn as_str(&self) -> &'static str {
match self {
Self::Server => "server",
@@ -39,6 +40,7 @@ impl std::fmt::Display for QaMode {
}
}
/// Parsed YAML front-matter fields from a story markdown file.
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct StoryMetadata {
pub name: Option<String>,
@@ -71,6 +73,7 @@ pub struct StoryMetadata {
pub mergemaster_attempted: Option<bool>,
}
/// Errors that can occur when parsing story front-matter metadata.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StoryMetaError {
MissingFrontMatter,