refactor: migrate handoff, notes, mcp, subagent, recall, anchors to .codewhale
- HANDOFF_RELATIVE_PATH → .codewhale/handoff.md with .deepseek fallback - load_handoff_block reads both paths, prefers .codewhale - ToolContext notes_path and mcp_config_path use resolve_project_state_dir - Sub-agent state path prefers .codewhale/state/ - Cycle archive (recall_archive) uses resolve_state_dir for sessions - Compaction anchors path prefers .codewhale/anchors.md - Updated marker constants and comments Part of #2231.
This commit is contained in:
@@ -1032,7 +1032,13 @@ fn read_workspace_anchors(workspace: Option<&Path>) -> Vec<String> {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
let anchors_path = ws.join(".deepseek").join("anchors.md");
|
||||
// Prefer .codewhale, fall back to .deepseek
|
||||
let primary = ws.join(".codewhale").join("anchors.md");
|
||||
let anchors_path = if primary.exists() {
|
||||
primary
|
||||
} else {
|
||||
ws.join(".deepseek").join("anchors.md")
|
||||
};
|
||||
let Ok(content) = std::fs::read_to_string(anchors_path) else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
@@ -53,7 +53,9 @@ impl Default for PromptSessionContext<'_> {
|
||||
/// A previous session writes it on exit / `/compact`; the next session reads
|
||||
/// it back on startup and prepends it to the system prompt so a fresh agent
|
||||
/// doesn't have to re-discover open blockers from scratch.
|
||||
pub const HANDOFF_RELATIVE_PATH: &str = ".deepseek/handoff.md";
|
||||
pub const HANDOFF_RELATIVE_PATH: &str = ".codewhale/handoff.md";
|
||||
/// Legacy handoff path for reading from existing installs.
|
||||
const LEGACY_HANDOFF_RELATIVE_PATH: &str = ".deepseek/handoff.md";
|
||||
|
||||
/// Per-file size cap for `instructions = [...]` entries (#454). Mirrors
|
||||
/// the existing project-context cap in `project_context::load_context_file`
|
||||
@@ -180,7 +182,12 @@ fn render_instructions_block(paths: &[PathBuf]) -> Option<String> {
|
||||
/// system-prompt block. Returns `None` when the file is absent or empty so
|
||||
/// callers can keep the default-uncluttered prompt for fresh workspaces.
|
||||
fn load_handoff_block(workspace: &Path) -> Option<String> {
|
||||
let path = workspace.join(HANDOFF_RELATIVE_PATH);
|
||||
let primary = workspace.join(HANDOFF_RELATIVE_PATH);
|
||||
let path = if primary.exists() {
|
||||
primary
|
||||
} else {
|
||||
workspace.join(LEGACY_HANDOFF_RELATIVE_PATH)
|
||||
};
|
||||
let raw = std::fs::read_to_string(&path).ok()?;
|
||||
let trimmed = raw.trim();
|
||||
if trimmed.is_empty() {
|
||||
@@ -373,7 +380,7 @@ pub const SUGGEST_APPROVAL: &str = include_str!("prompts/approvals/suggest.md");
|
||||
pub const NEVER_APPROVAL: &str = include_str!("prompts/approvals/never.md");
|
||||
|
||||
/// Compaction relay template — written into the system prompt so the
|
||||
/// model knows the format to use when writing `.deepseek/handoff.md`.
|
||||
/// model knows the format to use when writing `.codewhale/handoff.md`.
|
||||
pub const COMPACT_TEMPLATE: &str = include_str!("prompts/compact.md");
|
||||
|
||||
/// Memory hygiene guidance — appended to the system prompt only when the
|
||||
@@ -741,7 +748,7 @@ pub fn system_prompt_for_mode_with_context_skills_session_and_approval(
|
||||
}
|
||||
|
||||
// 5. Compaction relay template — so the model knows the format to use
|
||||
// when writing `.deepseek/handoff.md` on exit / `/compact`.
|
||||
// when writing `.codewhale/handoff.md` on exit / `/compact`.
|
||||
full_prompt.push_str("\n\n");
|
||||
full_prompt.push_str(COMPACT_TEMPLATE);
|
||||
|
||||
@@ -832,7 +839,7 @@ mod tests {
|
||||
|
||||
/// Discriminator unique to the injected relay block (not present in the
|
||||
/// agent prompt's own discussion of the convention).
|
||||
const HANDOFF_BLOCK_MARKER: &str = "left a relay artifact at `.deepseek/handoff.md`";
|
||||
const HANDOFF_BLOCK_MARKER: &str = "left a relay artifact at `.codewhale/handoff.md`";
|
||||
|
||||
fn contains_cjk(text: &str) -> bool {
|
||||
text.chars().any(|ch| {
|
||||
|
||||
@@ -162,11 +162,10 @@ fn archive_root(session_id: &str) -> Result<PathBuf, std::io::Error> {
|
||||
"Could not resolve home directory for cycle archive root",
|
||||
)
|
||||
})?;
|
||||
Ok(home
|
||||
.join(".deepseek")
|
||||
.join("sessions")
|
||||
.join(session_id)
|
||||
.join("cycles"))
|
||||
// Use resolved sessions dir (prefers ~/.codewhale/sessions)
|
||||
let sessions = codewhale_config::resolve_state_dir("sessions")
|
||||
.unwrap_or_else(|_| home.join(".deepseek").join("sessions"));
|
||||
Ok(sessions.join(session_id).join("cycles"))
|
||||
}
|
||||
|
||||
/// Enumerate all archive files for a session, sorted by cycle number ascending.
|
||||
|
||||
@@ -183,8 +183,9 @@ impl ToolContext {
|
||||
pub fn new(workspace: impl Into<PathBuf>) -> Self {
|
||||
let workspace = workspace.into();
|
||||
let shell_manager = new_shared_shell_manager(workspace.clone());
|
||||
let notes_path = workspace.join(".deepseek").join("notes.md");
|
||||
let mcp_config_path = workspace.join(".deepseek").join("mcp.json");
|
||||
// Prefer .codewhale, fall back to .deepseek for project-local state
|
||||
let notes_path = codewhale_config::resolve_project_state_dir(&workspace, "notes.md").1;
|
||||
let mcp_config_path = codewhale_config::resolve_project_state_dir(&workspace, "mcp.json").1;
|
||||
Self {
|
||||
workspace,
|
||||
shell_manager,
|
||||
|
||||
@@ -1845,6 +1845,11 @@ async fn subagent_session_projection(
|
||||
}
|
||||
|
||||
fn default_state_path(workspace: &Path) -> PathBuf {
|
||||
// Prefer .codewhale, fall back to .deepseek for project-local state
|
||||
let primary = workspace.join(".codewhale").join("state");
|
||||
if primary.exists() {
|
||||
return primary.join(SUBAGENT_STATE_FILE);
|
||||
}
|
||||
workspace
|
||||
.join(".deepseek")
|
||||
.join("state")
|
||||
|
||||
Reference in New Issue
Block a user