diff --git a/.gitignore b/.gitignore index f379530..679c7b9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,3 @@ /result /result-* /.claude/settings.local.json -# Per-worktree agent scratch (PR bodies, logs, notes); see the start-quest skill. -/.scratch/ diff --git a/assets/skills/start.md b/assets/skills/start.md index b3ebb75..af9ca94 100644 --- a/assets/skills/start.md +++ b/assets/skills/start.md @@ -15,7 +15,6 @@ Claim it as `quest guide` describes: `quest branch` names the branch and its bas Delete a claim you cannot finish (remote branch and worktree). Implement the quest until it is complete, or some blocker is hit, then create a PR against the base. -Keep scratch files (PR body, logs, notes) in the worktree's gitignored `.scratch/`. Never write to or clean up a directory other agents share, such as a session scratchpad. When done, explain the result in a few lines and summarize any issues encountered. diff --git a/docs/getting-started.md b/docs/getting-started.md index bf89756..ff9e89d 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -25,10 +25,9 @@ quest init ``` This writes a Quest stub for each shipped skill under `.claude/skills/`, links -`.agents/skills/` to the same tree when needed, adds `/.scratch/` to -`.gitignore`, creates `quest/README.md` when missing, and appends one line to -your root `AGENTS.md` or `CLAUDE.md` telling agents to run `quest guide` when -work mentions a quest. That line starts with `Quests: `; reword the rest freely, +`.agents/skills/` to the same tree when needed, creates `quest/README.md` when +missing, and appends one line to your root `AGENTS.md` or `CLAUDE.md` telling +agents to run `quest guide` when work mentions a quest. That line starts with `Quests: `; reword the rest freely, since init and uninstall recognize it by that prefix. Init refuses to overwrite an existing same-named skill that is not a Quest stub. @@ -84,6 +83,5 @@ GitHub issues, then run: quest uninstall ``` -Uninstall removes only Quest stubs that still match, the reference line, and the -`/.scratch/` ignore entry. It never deletes your quest tree, and completed plans -remain in Git history. Then remove the pin. +Uninstall removes only Quest stubs that still match and the reference line. It +never deletes your quest tree, and completed plans remain in Git history. Then remove the pin. diff --git a/src/setup.rs b/src/setup.rs index 1b7e700..644fd47 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,7 +1,7 @@ //! `quest init` and `quest uninstall`: install skill stubs and reverse it. //! -//! Init touches only stubs, one reference line, `/.scratch/` in `.gitignore`, and -//! an empty `quest/README.md` when missing. Uninstall never deletes the quest tree. +//! Init touches only stubs, one reference line, and an empty `quest/README.md` +//! when missing. Uninstall never deletes the quest tree. use std::fs; use std::path::{Path, PathBuf}; @@ -17,8 +17,6 @@ const REFERENCE_MARKER: &str = "Quests: "; /// Appended to the root agent instructions when Quest is installed. pub const REFERENCE_LINE: &str = "Quests: when work mentions a quest, run `quest guide` and follow it."; -const SCRATCH_IGNORE: &str = "/.scratch/"; - /// The skill directories Claude Code and Codex read. One holds the stubs and /// the other links to it. const SKILL_DIRS: [&str; 2] = [".claude/skills", ".agents/skills"]; @@ -65,16 +63,11 @@ pub fn init(root: &Path) -> Result> { changes.push(readme.into()); } - let ignore = Path::new(".gitignore"); - if append_line(root, ignore, SCRATCH_IGNORE, SCRATCH_IGNORE, false)? { - changes.push(ignore.into()); - } - let instructions = ["AGENTS.md", "CLAUDE.md"] .into_iter() .find(|name| root.join(name).is_file()) .unwrap_or("AGENTS.md"); - if append_line(root, Path::new(instructions), REFERENCE_MARKER, REFERENCE_LINE, true)? { + if append_line(root, Path::new(instructions), REFERENCE_MARKER, REFERENCE_LINE)? { changes.push(instructions.into()); } Ok(changes) @@ -113,12 +106,8 @@ pub fn uninstall(root: &Path) -> Result> { } } - for (path, marker) in [ - (".gitignore", SCRATCH_IGNORE), - ("AGENTS.md", REFERENCE_MARKER), - ("CLAUDE.md", REFERENCE_MARKER), - ] { - if remove_line(root, Path::new(path), marker)? { + for path in ["AGENTS.md", "CLAUDE.md"] { + if remove_line(root, Path::new(path), REFERENCE_MARKER)? { changes.push(path.into()); } } @@ -188,8 +177,8 @@ fn write(root: &Path, path: &Path, content: &str) -> Result<()> { } /// Append `line` unless a line already starts with `marker`, creating the file -/// if missing. `paragraph` separates it from existing content with a blank line. -fn append_line(root: &Path, path: &Path, marker: &str, line: &str, paragraph: bool) -> Result { +/// if missing, separated from existing content by a blank line. +fn append_line(root: &Path, path: &Path, marker: &str, line: &str) -> Result { let mut content = if root.join(path).is_file() { read(root, path)? } else { @@ -202,9 +191,7 @@ fn append_line(root: &Path, path: &Path, marker: &str, line: &str, paragraph: bo if !content.ends_with('\n') { content.push('\n'); } - if paragraph { - content.push('\n'); - } + content.push('\n'); } content.push_str(line); content.push('\n'); diff --git a/tests/init.rs b/tests/init.rs index bab95a6..2d535d4 100644 --- a/tests/init.rs +++ b/tests/init.rs @@ -24,10 +24,8 @@ fn init_creates_layout_and_is_idempotent() { assert!(dir.path().join(".claude/skills/quest-start/SKILL.md").is_file()); assert!(dir.path().join(".agents/skills/quest-start/SKILL.md").is_file()); assert!(dir.path().join("quest/README.md").is_file()); - assert!(dir.path().join(".gitignore").is_file()); + assert!(!dir.path().join(".gitignore").exists()); assert!(dir.path().join("AGENTS.md").is_file()); - let ignore = std::fs::read_to_string(dir.path().join(".gitignore")).unwrap(); - assert!(ignore.lines().any(|line| line == "/.scratch/")); let agents = std::fs::read_to_string(dir.path().join("AGENTS.md")).unwrap(); assert!(agents.contains(quest::setup::REFERENCE_LINE)); @@ -80,7 +78,6 @@ fn uninstall_round_trip_preserves_user_content() { let agents = std::fs::read_to_string(dir.path().join("AGENTS.md")).unwrap(); assert_eq!(agents, "# Repo\n\nUser rule.\n"); assert!(dir.path().join("quest/m0/plan.md").is_file()); - assert!(!dir.path().join(".gitignore").exists()); assert!(!dir.path().join(".claude").exists()); assert!(!dir.path().join(".agents").exists()); }