huskies: rename project from storkit to huskies
Rename all references from storkit to huskies across the codebase: - .storkit/ directory → .huskies/ - Binary name, Cargo package name, Docker image references - Server code, frontend code, config files, scripts - Fix script/test to build frontend before cargo clippy/test so merge worktrees have frontend/dist available for RustEmbed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ const SKIP_DIRS: &[&str] = &[
|
||||
];
|
||||
|
||||
/// Path components that indicate a worktree path that should be skipped.
|
||||
const SKIP_PATH_COMPONENTS: &[&str] = &[".storkit/worktrees"];
|
||||
const SKIP_PATH_COMPONENTS: &[&str] = &[".huskies/worktrees"];
|
||||
|
||||
/// Known-huge or machine-generated files that are excluded from the loc count
|
||||
/// even when they have a recognised source extension (e.g. `.json`, `.yaml`).
|
||||
@@ -88,10 +88,10 @@ fn loc_top_n(project_root: &std::path::Path, top_n: usize) -> String {
|
||||
if SKIP_DIRS.iter().any(|s| *s == name.as_ref()) {
|
||||
return false;
|
||||
}
|
||||
// Skip .storkit/worktrees — use relative path so the check
|
||||
// Skip .huskies/worktrees — use relative path so the check
|
||||
// doesn't exclude the project root itself when running
|
||||
// from inside a worktree (where the absolute path contains
|
||||
// ".storkit/worktrees").
|
||||
// ".huskies/worktrees").
|
||||
let rel = e
|
||||
.path()
|
||||
.strip_prefix(project_root)
|
||||
@@ -332,7 +332,7 @@ mod tests {
|
||||
let ctx = make_ctx(&agents, &ambient_rooms, repo_root, "");
|
||||
let output = handle_loc(&ctx).unwrap();
|
||||
assert!(
|
||||
!output.contains(".storkit/worktrees"),
|
||||
!output.contains(".huskies/worktrees"),
|
||||
"output must not include paths inside worktrees: {output}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ pub(super) fn handle_move(ctx: &CommandContext) -> Option<String> {
|
||||
'outer: for stage_dir in SEARCH_DIRS {
|
||||
let dir = ctx
|
||||
.project_root
|
||||
.join(".storkit")
|
||||
.join(".huskies")
|
||||
.join("work")
|
||||
.join(stage_dir);
|
||||
if !dir.exists() {
|
||||
@@ -242,7 +242,7 @@ mod tests {
|
||||
// Verify the file was actually moved.
|
||||
let new_path = tmp
|
||||
.path()
|
||||
.join(".storkit/work/2_current/42_story_some_feature.md");
|
||||
.join(".huskies/work/2_current/42_story_some_feature.md");
|
||||
assert!(new_path.exists(), "story file should be in 2_current/");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::CommandContext;
|
||||
|
||||
/// Show implementation summary for a story identified by its number.
|
||||
///
|
||||
/// Finds the `storkit: merge {story_id}` commit on master, displays the
|
||||
/// Finds the `huskies: merge {story_id}` commit on master, displays the
|
||||
/// git diff --stat (files changed with line counts), and extracts key
|
||||
/// function/struct/type names added or modified in the implementation.
|
||||
/// Returns a friendly message when no merge commit is found.
|
||||
@@ -82,11 +82,11 @@ pub(super) fn handle_overview(ctx: &CommandContext) -> Option<String> {
|
||||
/// Find the merge commit hash for a story by its numeric ID.
|
||||
///
|
||||
/// Searches git log for a commit whose subject matches
|
||||
/// `storkit: merge {num}_*` or the legacy `story-kit: merge {num}_*`.
|
||||
/// `huskies: merge {num}_*` or the legacy `story-kit: merge {num}_*`.
|
||||
fn find_story_merge_commit(root: &std::path::Path, num_str: &str) -> Option<String> {
|
||||
use std::process::Command;
|
||||
// Match both the current prefix and the legacy one from before the rename.
|
||||
let grep_pattern = format!("(storkit|story-kit): merge {num_str}_");
|
||||
let grep_pattern = format!("(huskies|storkit|story-kit): merge {num_str}_");
|
||||
let output = Command::new("git")
|
||||
.args([
|
||||
"log",
|
||||
@@ -116,7 +116,7 @@ fn find_story_name(root: &std::path::Path, num_str: &str) -> Option<String> {
|
||||
"6_archived",
|
||||
];
|
||||
for stage in &stages {
|
||||
let dir = root.join(".storkit").join("work").join(stage);
|
||||
let dir = root.join(".huskies").join("work").join(stage);
|
||||
if !dir.exists() {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ fn wizard_status_reply(ctx: &CommandContext) -> String {
|
||||
match WizardState::load(ctx.project_root) {
|
||||
Some(state) => format_wizard_state(&state),
|
||||
None => {
|
||||
"No setup wizard active. Run `storkit init` in the project root to begin.".to_string()
|
||||
"No setup wizard active. Run `huskies init` in the project root to begin.".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,13 +215,13 @@ mod tests {
|
||||
let rooms = Arc::new(Mutex::new(HashSet::new()));
|
||||
let ctx = make_ctx("", dir.path(), &agents, &rooms);
|
||||
let result = handle_setup(&ctx).unwrap();
|
||||
assert!(result.contains("storkit init"));
|
||||
assert!(result.contains("huskies init"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_with_wizard_shows_status() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".storkit")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".huskies")).unwrap();
|
||||
WizardState::init_if_missing(dir.path());
|
||||
let agents = Arc::new(crate::agents::AgentPool::new_test(4001));
|
||||
let rooms = Arc::new(Mutex::new(HashSet::new()));
|
||||
@@ -233,7 +233,7 @@ mod tests {
|
||||
#[test]
|
||||
fn setup_skip_advances_wizard() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".storkit")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".huskies")).unwrap();
|
||||
WizardState::init_if_missing(dir.path());
|
||||
let agents = Arc::new(crate::agents::AgentPool::new_test(4002));
|
||||
let rooms = Arc::new(Mutex::new(HashSet::new()));
|
||||
@@ -247,7 +247,7 @@ mod tests {
|
||||
#[test]
|
||||
fn setup_confirm_advances_wizard() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".storkit")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".huskies")).unwrap();
|
||||
WizardState::init_if_missing(dir.path());
|
||||
let agents = Arc::new(crate::agents::AgentPool::new_test(4003));
|
||||
let rooms = Arc::new(Mutex::new(HashSet::new()));
|
||||
@@ -261,7 +261,7 @@ mod tests {
|
||||
#[test]
|
||||
fn setup_retry_resets_step() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".storkit")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".huskies")).unwrap();
|
||||
WizardState::init_if_missing(dir.path());
|
||||
// Stage some content first.
|
||||
{
|
||||
@@ -299,7 +299,7 @@ mod tests {
|
||||
#[test]
|
||||
fn setup_generate_marks_generating_and_returns_hint() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".storkit")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".huskies")).unwrap();
|
||||
WizardState::init_if_missing(dir.path());
|
||||
let agents = Arc::new(crate::agents::AgentPool::new_test(4006));
|
||||
let rooms = Arc::new(Mutex::new(HashSet::new()));
|
||||
@@ -317,7 +317,7 @@ mod tests {
|
||||
fn setup_generate_bare_project_asks_user() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
// Bare project — only scaffolding files
|
||||
std::fs::create_dir_all(dir.path().join(".storkit")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".huskies")).unwrap();
|
||||
WizardState::init_if_missing(dir.path());
|
||||
let agents = Arc::new(crate::agents::AgentPool::new_test(4007));
|
||||
let rooms = Arc::new(Mutex::new(HashSet::new()));
|
||||
|
||||
@@ -34,7 +34,7 @@ pub(super) fn handle_show(ctx: &CommandContext) -> Option<String> {
|
||||
for stage in &stages {
|
||||
let dir = ctx
|
||||
.project_root
|
||||
.join(".storkit")
|
||||
.join(".huskies")
|
||||
.join("work")
|
||||
.join(stage);
|
||||
if !dir.exists() {
|
||||
|
||||
@@ -54,7 +54,7 @@ pub(super) fn story_short_label(stem: &str, name: Option<&str>) -> String {
|
||||
/// Returns `true` when the story has `blocked: true` set (retry limit reached).
|
||||
fn read_story_blocked(project_root: &std::path::Path, stage_dir: &str, stem: &str) -> bool {
|
||||
let path = project_root
|
||||
.join(".storkit")
|
||||
.join(".huskies")
|
||||
.join("work")
|
||||
.join(stage_dir)
|
||||
.join(format!("{stem}.md"));
|
||||
@@ -93,7 +93,7 @@ fn read_stage_items(
|
||||
stage_dir: &str,
|
||||
) -> Vec<(String, Option<String>)> {
|
||||
let dir = project_root
|
||||
.join(".storkit")
|
||||
.join(".huskies")
|
||||
.join("work")
|
||||
.join(stage_dir);
|
||||
if !dir.exists() {
|
||||
@@ -346,7 +346,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
// Write a story file with a front-matter name
|
||||
@@ -375,7 +375,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("293_story_register_all_bot_commands.md");
|
||||
@@ -413,7 +413,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("293_story_register_all_bot_commands.md");
|
||||
@@ -436,7 +436,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("293_story_register_all_bot_commands.md");
|
||||
@@ -480,7 +480,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("42_story_idle.md");
|
||||
@@ -502,7 +502,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("42_story_blocked.md");
|
||||
@@ -524,7 +524,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("42_story_idle.md");
|
||||
@@ -578,7 +578,7 @@ mod tests {
|
||||
fn read_story_blocked_returns_true_when_blocked() {
|
||||
use tempfile::TempDir;
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
std::fs::write(
|
||||
stage_dir.join("42_story_foo.md"),
|
||||
@@ -592,7 +592,7 @@ mod tests {
|
||||
fn read_story_blocked_returns_false_when_not_blocked() {
|
||||
use tempfile::TempDir;
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
std::fs::write(
|
||||
stage_dir.join("42_story_foo.md"),
|
||||
@@ -610,7 +610,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("42_story_idle.md");
|
||||
@@ -632,7 +632,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let stage_dir = tmp.path().join(".storkit/work/2_current");
|
||||
let stage_dir = tmp.path().join(".huskies/work/2_current");
|
||||
std::fs::create_dir_all(&stage_dir).unwrap();
|
||||
|
||||
let story_path = stage_dir.join("42_story_blocked.md");
|
||||
|
||||
@@ -28,7 +28,7 @@ pub(super) fn handle_triage(ctx: &CommandContext) -> Option<String> {
|
||||
|
||||
let current_dir = ctx
|
||||
.project_root
|
||||
.join(".storkit")
|
||||
.join(".huskies")
|
||||
.join("work")
|
||||
.join("2_current");
|
||||
|
||||
@@ -179,7 +179,7 @@ fn build_triage_dump(
|
||||
// ---- Agent log tail ----
|
||||
let log_dir = ctx
|
||||
.project_root
|
||||
.join(".storkit")
|
||||
.join(".huskies")
|
||||
.join("logs")
|
||||
.join(story_id);
|
||||
match latest_log_file(&log_dir) {
|
||||
|
||||
@@ -45,7 +45,7 @@ pub(crate) fn unblock_by_number(project_root: &Path, story_number: &str) -> Stri
|
||||
let mut found: Option<(std::path::PathBuf, String)> = None;
|
||||
|
||||
'outer: for stage_dir in SEARCH_DIRS {
|
||||
let dir = project_root.join(".storkit").join("work").join(stage_dir);
|
||||
let dir = project_root.join(".huskies").join("work").join(stage_dir);
|
||||
if !dir.exists() {
|
||||
continue;
|
||||
}
|
||||
@@ -252,7 +252,7 @@ mod tests {
|
||||
);
|
||||
|
||||
let contents = std::fs::read_to_string(
|
||||
tmp.path().join(".storkit/work/2_current/7_story_stuck.md"),
|
||||
tmp.path().join(".huskies/work/2_current/7_story_stuck.md"),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
|
||||
@@ -77,7 +77,7 @@ fn find_last_release_tag(root: &std::path::Path) -> Option<String> {
|
||||
if tag.is_empty() { None } else { Some(tag) }
|
||||
}
|
||||
|
||||
/// Return the subjects of all `storkit: merge …` commits reachable from HEAD
|
||||
/// Return the subjects of all `huskies: merge …` commits reachable from HEAD
|
||||
/// but not from `since_tag` (or all commits when `since_tag` is `None`).
|
||||
fn list_merge_commits_since(
|
||||
root: &std::path::Path,
|
||||
@@ -97,7 +97,7 @@ fn list_merge_commits_since(
|
||||
"--format=%s",
|
||||
"--extended-regexp",
|
||||
"--grep",
|
||||
"(storkit|story-kit): merge [0-9]+_",
|
||||
"(huskies|storkit|story-kit): merge [0-9]+_",
|
||||
])
|
||||
.current_dir(root)
|
||||
.output()
|
||||
@@ -115,14 +115,14 @@ fn list_merge_commits_since(
|
||||
}
|
||||
|
||||
/// Parse a story number and slug from a merge commit subject like
|
||||
/// `storkit: merge 386_story_unreleased_command`.
|
||||
/// `huskies: merge 386_story_unreleased_command`.
|
||||
///
|
||||
/// Returns `(story_number, slug_remainder)` or `None` if the subject doesn't
|
||||
/// match the expected pattern.
|
||||
fn parse_story_from_subject(subject: &str) -> Option<(u64, String)> {
|
||||
// Match "storkit: merge NNN_rest" or "story-kit: merge NNN_rest"
|
||||
// Match "huskies: merge NNN_rest" or "story-kit: merge NNN_rest"
|
||||
let rest = subject
|
||||
.strip_prefix("storkit: merge ")
|
||||
.strip_prefix("huskies: merge ")
|
||||
.or_else(|| subject.strip_prefix("story-kit: merge "))?;
|
||||
|
||||
let (num_str, slug) = rest.split_once('_')?;
|
||||
@@ -159,7 +159,7 @@ fn find_story_name(root: &std::path::Path, num_str: &str) -> Option<String> {
|
||||
"6_archived",
|
||||
];
|
||||
for stage in STAGES {
|
||||
let dir = root.join(".storkit").join("work").join(stage);
|
||||
let dir = root.join(".huskies").join("work").join(stage);
|
||||
if !dir.exists() {
|
||||
continue;
|
||||
}
|
||||
@@ -271,8 +271,8 @@ mod tests {
|
||||
// -- parse_story_from_subject ------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn parse_story_storkit_prefix() {
|
||||
let result = parse_story_from_subject("storkit: merge 386_story_unreleased_command");
|
||||
fn parse_story_huskies_prefix() {
|
||||
let result = parse_story_from_subject("huskies: merge 386_story_unreleased_command");
|
||||
assert_eq!(result, Some((386, "story_unreleased_command".to_string())));
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_story_no_underscore_after_number() {
|
||||
let result = parse_story_from_subject("storkit: merge 123");
|
||||
let result = parse_story_from_subject("huskies: merge 123");
|
||||
assert_eq!(result, None);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user