huskies: merge 966
This commit is contained in:
@@ -7,7 +7,7 @@ max_turns = 200
|
||||
max_tool_turns = 80
|
||||
max_budget_usd = 5.00
|
||||
disallowed_tools = ["ScheduleWakeup"]
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. Read CLAUDE.md first, then .huskies/README.md for the dev process, .huskies/specs/00_CONTEXT.md for what this project does, and .huskies/specs/tech/STACK.md for the tech stack and source map. The story details are in your prompt above. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. The story details are in your prompt above. See .huskies/specs/tech/STACK.md for the tech stack and source map when needed. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
system_prompt = "You are a full-stack engineer working autonomously in a git worktree. Step 0: Before anything else, call `git_status` and `git_log` + `git_diff` against `master..HEAD` to discover any prior-session work in this worktree — uncommitted changes AND commits already on the feature branch. If either shows progress, RESUME from there; do not re-explore the codebase from scratch. To read story content, ACs, or description, call the `get_story_todos` MCP tool — do NOT search for a story `.md` file on disk; story content is CRDT-only. Do NOT run run_tests at the start of a new session on a freshly-forked worktree — master is gated and assumed green. Only run run_tests after you have made changes, to validate your own diff. Always run run_tests before committing — do not commit until tests pass. run_tests blocks server-side and returns the full result; do not poll get_test_result. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done. Before committing, run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` to check doc coverage on your changed files and address every missing-docs direction it prints. Do not accept stories, move them between stages, or merge to master — the server handles that. For bugs, trust the story description and make surgical fixes. For refactors that delete code or change function signatures, delete first and let the compiler error list be your guide to call sites — do not pre-read files trying to predict what will break. Each compile error is one mechanical fix; resist the urge to explore. Run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` BEFORE you commit and address every direction it prints. For cross-stack stories (any story that touches more than 5 files OR more than 2 modules), commit progressively after each completed acceptance criterion or natural unit of work — do not save everything for a single end-of-story commit. Use `wip(story-{id}): {AC summary}` for intermediate commits and `{type}({id}): {summary}` for the final commit. This rule does NOT apply to small bug fixes or single-AC stories — for those, a single commit at the end is correct. For fast compile-error feedback while iterating, call `run_check` (runs `script/check`). Use `run_tests` only to validate the full pipeline before committing."
|
||||
|
||||
[[agent]]
|
||||
@@ -19,7 +19,7 @@ max_turns = 200
|
||||
max_tool_turns = 80
|
||||
max_budget_usd = 5.00
|
||||
disallowed_tools = ["ScheduleWakeup"]
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. Read CLAUDE.md first, then .huskies/README.md for the dev process, .huskies/specs/00_CONTEXT.md for what this project does, and .huskies/specs/tech/STACK.md for the tech stack and source map. The story details are in your prompt above. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. The story details are in your prompt above. See .huskies/specs/tech/STACK.md for the tech stack and source map when needed. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
system_prompt = "You are a full-stack engineer working autonomously in a git worktree. Step 0: Before anything else, call `git_status` and `git_log` + `git_diff` against `master..HEAD` to discover any prior-session work in this worktree — uncommitted changes AND commits already on the feature branch. If either shows progress, RESUME from there; do not re-explore the codebase from scratch. To read story content, ACs, or description, call the `get_story_todos` MCP tool — do NOT search for a story `.md` file on disk; story content is CRDT-only. Do NOT run run_tests at the start of a new session on a freshly-forked worktree — master is gated and assumed green. Only run run_tests after you have made changes, to validate your own diff. Always run run_tests before committing — do not commit until tests pass. run_tests blocks server-side and returns the full result; do not poll get_test_result. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done. Before committing, run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` to check doc coverage on your changed files and address every missing-docs direction it prints. Do not accept stories, move them between stages, or merge to master — the server handles that. For bugs, trust the story description and make surgical fixes. For refactors that delete code or change function signatures, delete first and let the compiler error list be your guide to call sites — do not pre-read files trying to predict what will break. Each compile error is one mechanical fix; resist the urge to explore. Run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` BEFORE you commit and address every direction it prints. For cross-stack stories (any story that touches more than 5 files OR more than 2 modules), commit progressively after each completed acceptance criterion or natural unit of work — do not save everything for a single end-of-story commit. Use `wip(story-{id}): {AC summary}` for intermediate commits and `{type}({id}): {summary}` for the final commit. This rule does NOT apply to small bug fixes or single-AC stories — for those, a single commit at the end is correct. For fast compile-error feedback while iterating, call `run_check` (runs `script/check`). Use `run_tests` only to validate the full pipeline before committing."
|
||||
|
||||
[[agent]]
|
||||
@@ -31,7 +31,7 @@ max_turns = 200
|
||||
max_tool_turns = 80
|
||||
max_budget_usd = 5.00
|
||||
disallowed_tools = ["ScheduleWakeup"]
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. Read CLAUDE.md first, then .huskies/README.md for the dev process, .huskies/specs/00_CONTEXT.md for what this project does, and .huskies/specs/tech/STACK.md for the tech stack and source map. The story details are in your prompt above. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. The story details are in your prompt above. See .huskies/specs/tech/STACK.md for the tech stack and source map when needed. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
system_prompt = "You are a full-stack engineer working autonomously in a git worktree. Step 0: Before anything else, call `git_status` and `git_log` + `git_diff` against `master..HEAD` to discover any prior-session work in this worktree — uncommitted changes AND commits already on the feature branch. If either shows progress, RESUME from there; do not re-explore the codebase from scratch. To read story content, ACs, or description, call the `get_story_todos` MCP tool — do NOT search for a story `.md` file on disk; story content is CRDT-only. Do NOT run run_tests at the start of a new session on a freshly-forked worktree — master is gated and assumed green. Only run run_tests after you have made changes, to validate your own diff. Always run run_tests before committing — do not commit until tests pass. run_tests blocks server-side and returns the full result; do not poll get_test_result. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done. Before committing, run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` to check doc coverage on your changed files and address every missing-docs direction it prints. Do not accept stories, move them between stages, or merge to master — the server handles that. For bugs, trust the story description and make surgical fixes. For refactors that delete code or change function signatures, delete first and let the compiler error list be your guide to call sites — do not pre-read files trying to predict what will break. Each compile error is one mechanical fix; resist the urge to explore. Run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` BEFORE you commit and address every direction it prints. For cross-stack stories (any story that touches more than 5 files OR more than 2 modules), commit progressively after each completed acceptance criterion or natural unit of work — do not save everything for a single end-of-story commit. Use `wip(story-{id}): {AC summary}` for intermediate commits and `{type}({id}): {summary}` for the final commit. This rule does NOT apply to small bug fixes or single-AC stories — for those, a single commit at the end is correct. For fast compile-error feedback while iterating, call `run_check` (runs `script/check`). Use `run_tests` only to validate the full pipeline before committing."
|
||||
|
||||
[[agent]]
|
||||
@@ -135,7 +135,7 @@ max_turns = 200
|
||||
max_tool_turns = 80
|
||||
max_budget_usd = 20.00
|
||||
disallowed_tools = ["ScheduleWakeup"]
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. Read CLAUDE.md first, then .huskies/README.md for the dev process, .huskies/specs/00_CONTEXT.md for what this project does, and .huskies/specs/tech/STACK.md for the tech stack and source map. The story details are in your prompt above. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
prompt ="You are working in a git worktree on story {{story_id}}. The story details are in your prompt above. See .huskies/specs/tech/STACK.md for the tech stack and source map when needed. The worktree and feature branch already exist - do not create them.\n\n## Your workflow\n1. Read the story and understand the acceptance criteria.\n2. Implement the changes.\n3. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done.\n4. Run the run_tests MCP tool. It blocks server-side until tests finish (up to 20 minutes) and returns the full result. Do NOT call get_test_result — run_tests already gives you the pass/fail outcome.\n5. If tests fail, fix the failures and run run_tests again. Do not commit until tests pass.\n6. Once tests pass, commit your work with a descriptive message and exit.\n\nDo NOT accept stories, move them between stages, or merge to master. The server handles all of that after you exit.\n\n## Bug Workflow: Trust the Story, Act Fast\nWhen working on bugs:\n1. READ THE STORY DESCRIPTION FIRST. If it specifies exact files, functions, and line numbers — go directly there and make the fix.\n2. If the story does NOT specify the exact location, investigate with targeted grep.\n3. Fix with a surgical, minimal change.\n4. Run tests, fix failures, commit and exit.\n5. Write commit messages that explain what broke and why."
|
||||
system_prompt = "You are a senior full-stack engineer working autonomously in a git worktree. Step 0: Before anything else, call `git_status` and `git_log` + `git_diff` against `master..HEAD` to discover any prior-session work in this worktree — uncommitted changes AND commits already on the feature branch. If either shows progress, RESUME from there; do not re-explore the codebase from scratch. To read story content, ACs, or description, call the `get_story_todos` MCP tool — do NOT search for a story `.md` file on disk; story content is CRDT-only. You handle complex tasks requiring deep architectural understanding. Do NOT run run_tests at the start of a new session on a freshly-forked worktree — master is gated and assumed green. Only run run_tests after you have made changes, to validate your own diff. Always run run_tests before committing — do not commit until tests pass. run_tests blocks server-side and returns the full result; do not poll get_test_result. As you complete each acceptance criterion, call check_criterion MCP tool to mark it done. Before committing, run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` to check doc coverage on your changed files and address every missing-docs direction it prints. Do not accept stories, move them between stages, or merge to master — the server handles that. For bugs, trust the story description and make surgical fixes. For refactors that delete code or change function signatures, delete first and let the compiler error list be your guide to call sites — do not pre-read files trying to predict what will break. Each compile error is one mechanical fix; resist the urge to explore. Run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` BEFORE you commit and address every direction it prints. For cross-stack stories (any story that touches more than 5 files OR more than 2 modules), commit progressively after each completed acceptance criterion or natural unit of work — do not save everything for a single end-of-story commit. Use `wip(story-{id}): {AC summary}` for intermediate commits and `{type}({id}): {summary}` for the final commit. This rule does NOT apply to small bug fixes or single-AC stories — for those, a single commit at the end is correct. For fast compile-error feedback while iterating, call `run_check` (runs `script/check`). Use `run_tests` only to validate the full pipeline before committing."
|
||||
|
||||
[[agent]]
|
||||
|
||||
@@ -1,66 +1,117 @@
|
||||
//! Project-local agent prompt layer.
|
||||
//!
|
||||
//! Reads `.huskies/AGENT.md` from the project root and appends its content to
|
||||
//! the baked-in agent prompt at spawn time. This lets projects record
|
||||
//! non-obvious facts (directory conventions, known traps, etc.) that every
|
||||
//! agent should know without modifying the shared agent configuration.
|
||||
//! Reads a fixed set of orientation files from the project root and concatenates
|
||||
//! them into a single bundle that is appended to every coder's system prompt at
|
||||
//! spawn time. This eliminates the cold-start tax where agents spent early turns
|
||||
//! reading files that could have been preloaded.
|
||||
//!
|
||||
//! Files bundled (in order):
|
||||
//! - `CLAUDE.md`
|
||||
//! - `.huskies/README.md`
|
||||
//! - `.huskies/specs/00_CONTEXT.md`
|
||||
//! - `.huskies/AGENT.md`
|
||||
//!
|
||||
//! `STACK.md` is intentionally excluded — it is large and changes often; agents
|
||||
//! should grep it on demand.
|
||||
//!
|
||||
//! Behaviour contract:
|
||||
//! - If the file is missing or empty the caller receives `None`; agents spawn
|
||||
//! normally with no warnings or errors.
|
||||
//! - If the file exists and is non-empty, the content is returned and an
|
||||
//! INFO-level log line is emitted with the file path and byte count.
|
||||
//! - The file is read fresh on every agent spawn — no caching.
|
||||
//! - Files that are missing or empty are skipped silently (no error, no section).
|
||||
//! - If all files are absent or empty, `None` is returned and agents spawn normally.
|
||||
//! - A single INFO-level log line is emitted with the total byte count and the
|
||||
//! list of files that were actually included.
|
||||
//! - Files are read fresh on every agent spawn — no caching.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
/// Attempt to load the project-local agent prompt from `.huskies/AGENT.md`.
|
||||
/// Files to bundle into the orientation prompt, in order.
|
||||
/// Paths are relative to the project root.
|
||||
const ORIENTATION_FILES: &[&str] = &[
|
||||
"CLAUDE.md",
|
||||
".huskies/README.md",
|
||||
".huskies/specs/00_CONTEXT.md",
|
||||
".huskies/AGENT.md",
|
||||
];
|
||||
|
||||
/// Attempt to load the project-local agent prompt by concatenating orientation
|
||||
/// files from the project root.
|
||||
///
|
||||
/// Returns `Some(content)` when the file exists and is non-empty, or `None`
|
||||
/// when the file is absent or empty. Never returns an error; any I/O problem
|
||||
/// is silently treated as "no local prompt".
|
||||
/// Returns `Some(bundle)` when at least one file exists and is non-empty, with
|
||||
/// sections separated by `=== <file> ===` delimiters. Returns `None` when all
|
||||
/// files are absent or empty. Never returns an error.
|
||||
pub fn read_project_local_prompt(project_root: &Path) -> Option<String> {
|
||||
let path = project_root.join(".huskies/AGENT.md");
|
||||
let content = std::fs::read_to_string(&path).ok()?;
|
||||
let mut sections: Vec<(&str, String)> = Vec::new();
|
||||
|
||||
for &rel_path in ORIENTATION_FILES {
|
||||
let abs_path = project_root.join(rel_path);
|
||||
let Ok(content) = std::fs::read_to_string(&abs_path) else {
|
||||
continue;
|
||||
};
|
||||
let trimmed = content.trim();
|
||||
if trimmed.is_empty() {
|
||||
continue;
|
||||
}
|
||||
sections.push((rel_path, trimmed.to_string()));
|
||||
}
|
||||
|
||||
if sections.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let included_files: Vec<&str> = sections.iter().map(|(name, _)| *name).collect();
|
||||
let mut bundle = String::new();
|
||||
for (i, (name, content)) in sections.iter().enumerate() {
|
||||
if i > 0 {
|
||||
bundle.push('\n');
|
||||
}
|
||||
bundle.push_str(&format!("=== {name} ===\n"));
|
||||
bundle.push_str(content);
|
||||
}
|
||||
|
||||
crate::slog!(
|
||||
"[agents] project-local prompt loaded: {} ({} bytes)",
|
||||
path.display(),
|
||||
trimmed.len()
|
||||
"[agents] orientation bundle: {} bytes, files: [{}]",
|
||||
bundle.len(),
|
||||
included_files.join(", ")
|
||||
);
|
||||
Some(trimmed.to_string())
|
||||
|
||||
Some(bundle)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn write_file(base: &Path, rel: &str, content: &str) {
|
||||
let path = base.join(rel);
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent).unwrap();
|
||||
}
|
||||
std::fs::write(path, content).unwrap();
|
||||
}
|
||||
|
||||
// ── Legacy tests (kept passing) ──────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn returns_none_when_file_absent() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let result = read_project_local_prompt(tmp.path());
|
||||
assert!(result.is_none(), "missing file must return None");
|
||||
assert!(result.is_none(), "all files missing must return None");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_none_when_file_empty() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let huskies_dir = tmp.path().join(".huskies");
|
||||
std::fs::create_dir_all(&huskies_dir).unwrap();
|
||||
std::fs::write(huskies_dir.join("AGENT.md"), "").unwrap();
|
||||
write_file(tmp.path(), ".huskies/AGENT.md", "");
|
||||
let result = read_project_local_prompt(tmp.path());
|
||||
assert!(result.is_none(), "empty file must return None");
|
||||
assert!(
|
||||
result.is_none(),
|
||||
"empty file must return None when others absent"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_none_when_file_whitespace_only() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let huskies_dir = tmp.path().join(".huskies");
|
||||
std::fs::create_dir_all(&huskies_dir).unwrap();
|
||||
std::fs::write(huskies_dir.join("AGENT.md"), " \n\n ").unwrap();
|
||||
write_file(tmp.path(), ".huskies/AGENT.md", " \n\n ");
|
||||
let result = read_project_local_prompt(tmp.path());
|
||||
assert!(result.is_none(), "whitespace-only file must return None");
|
||||
}
|
||||
@@ -68,10 +119,12 @@ mod tests {
|
||||
#[test]
|
||||
fn returns_content_when_file_non_empty() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let huskies_dir = tmp.path().join(".huskies");
|
||||
std::fs::create_dir_all(&huskies_dir).unwrap();
|
||||
let marker = "DISTINCTIVE_MARKER_XYZ42";
|
||||
std::fs::write(huskies_dir.join("AGENT.md"), format!("# Hints\n{marker}\n")).unwrap();
|
||||
write_file(
|
||||
tmp.path(),
|
||||
".huskies/AGENT.md",
|
||||
&format!("# Hints\n{marker}\n"),
|
||||
);
|
||||
let result = read_project_local_prompt(tmp.path());
|
||||
assert!(result.is_some(), "non-empty file must return Some");
|
||||
let content = result.unwrap();
|
||||
@@ -83,13 +136,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn appended_to_prompt_integration() {
|
||||
// Simulates the start.rs usage: marker appears in the constructed
|
||||
// system prompt when the file is present, absent when it is not.
|
||||
let tmp_with = tempfile::tempdir().unwrap();
|
||||
let huskies_dir = tmp_with.path().join(".huskies");
|
||||
std::fs::create_dir_all(&huskies_dir).unwrap();
|
||||
let marker = "INTEGRATION_MARKER_601";
|
||||
std::fs::write(huskies_dir.join("AGENT.md"), marker).unwrap();
|
||||
write_file(tmp_with.path(), ".huskies/AGENT.md", marker);
|
||||
|
||||
let base_prompt = "You are a coder agent.".to_string();
|
||||
let local = read_project_local_prompt(tmp_with.path());
|
||||
@@ -102,7 +151,6 @@ mod tests {
|
||||
"marker must appear in effective prompt when file present: {effective}"
|
||||
);
|
||||
|
||||
// Without the file
|
||||
let tmp_without = tempfile::tempdir().unwrap();
|
||||
let local2 = read_project_local_prompt(tmp_without.path());
|
||||
assert!(local2.is_none(), "no marker when file absent");
|
||||
@@ -115,4 +163,98 @@ mod tests {
|
||||
"marker must NOT appear in effective prompt when file absent: {effective2}"
|
||||
);
|
||||
}
|
||||
|
||||
// ── New tests for four-file bundle behaviour ──────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn all_four_files_present_concatenated() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
write_file(tmp.path(), "CLAUDE.md", "claude content");
|
||||
write_file(tmp.path(), ".huskies/README.md", "readme content");
|
||||
write_file(
|
||||
tmp.path(),
|
||||
".huskies/specs/00_CONTEXT.md",
|
||||
"context content",
|
||||
);
|
||||
write_file(tmp.path(), ".huskies/AGENT.md", "agent content");
|
||||
|
||||
let result = read_project_local_prompt(tmp.path()).unwrap();
|
||||
assert!(
|
||||
result.contains("claude content"),
|
||||
"must include CLAUDE.md: {result}"
|
||||
);
|
||||
assert!(
|
||||
result.contains("readme content"),
|
||||
"must include README.md: {result}"
|
||||
);
|
||||
assert!(
|
||||
result.contains("context content"),
|
||||
"must include 00_CONTEXT.md: {result}"
|
||||
);
|
||||
assert!(
|
||||
result.contains("agent content"),
|
||||
"must include AGENT.md: {result}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn some_files_missing_only_present_in_bundle() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
write_file(tmp.path(), "CLAUDE.md", "claude only");
|
||||
// README.md, 00_CONTEXT.md, AGENT.md absent
|
||||
|
||||
let result = read_project_local_prompt(tmp.path()).unwrap();
|
||||
assert!(
|
||||
result.contains("claude only"),
|
||||
"must include CLAUDE.md: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("=== .huskies/README.md ==="),
|
||||
"absent README must not have a section delimiter: {result}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_files_missing_returns_none() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let result = read_project_local_prompt(tmp.path());
|
||||
assert!(result.is_none(), "all absent must return None");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn section_delimiters_appear_between_files() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
write_file(tmp.path(), "CLAUDE.md", "first");
|
||||
write_file(tmp.path(), ".huskies/AGENT.md", "last");
|
||||
|
||||
let result = read_project_local_prompt(tmp.path()).unwrap();
|
||||
assert!(
|
||||
result.contains("=== CLAUDE.md ==="),
|
||||
"must have CLAUDE.md delimiter: {result}"
|
||||
);
|
||||
assert!(
|
||||
result.contains("=== .huskies/AGENT.md ==="),
|
||||
"must have AGENT.md delimiter: {result}"
|
||||
);
|
||||
// Delimiter for CLAUDE.md must appear before its content
|
||||
let claude_delim = result.find("=== CLAUDE.md ===").unwrap();
|
||||
let first_content = result.find("first").unwrap();
|
||||
assert!(
|
||||
claude_delim < first_content,
|
||||
"delimiter must precede content"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stack_md_not_included() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
write_file(tmp.path(), "CLAUDE.md", "hello");
|
||||
write_file(tmp.path(), ".huskies/specs/tech/STACK.md", "stack content");
|
||||
|
||||
let result = read_project_local_prompt(tmp.path()).unwrap();
|
||||
assert!(
|
||||
!result.contains("stack content"),
|
||||
"STACK.md must not appear in bundle: {result}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user