From 3ac34530578b9a6f59bcea6b5aeefd97eb03d588 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sat, 28 Feb 2026 18:46:11 -0800 Subject: Move artifacts to ~/.claude-flow/ (outside repo) - Store session artifacts in ~/.claude-flow/projects/{projectId}/sessions/{sessionId}/ - Artifacts no longer live in project directory - can't be accidentally committed - Remove .claude-flow/ from .gitignore (not needed anymore) - Update all IPC handlers and renderer to use projectId instead of projectPath - Update prompts to remove worktree references - Update README with new storage location --- src/main/claude/index.ts | 65 ++++++++++++++++++----------------------------- src/main/claude/phases.ts | 55 +++++++++++++-------------------------- 2 files changed, 43 insertions(+), 77 deletions(-) (limited to 'src/main/claude') diff --git a/src/main/claude/index.ts b/src/main/claude/index.ts index 4d8909b..b8c9c07 100644 --- a/src/main/claude/index.ts +++ b/src/main/claude/index.ts @@ -6,16 +6,28 @@ import { getProject } from "../db/projects"; import { updateSession } from "../db/sessions"; import fs from "node:fs"; import path from "node:path"; +import os from "node:os"; // Track active queries by session ID const activeQueries = new Map(); +// Global storage in home directory +const GLOBAL_CLAUDE_FLOW_DIR = path.join(os.homedir(), ".claude-flow"); + function ensureDir(dirPath: string): void { if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } } +function getProjectDir(projectId: string): string { + return path.join(GLOBAL_CLAUDE_FLOW_DIR, "projects", projectId); +} + +function getSessionDir(projectId: string, sessionId: string): string { + return path.join(getProjectDir(projectId), "sessions", sessionId); +} + export interface SendMessageOptions { session: Session; message: string; @@ -30,8 +42,8 @@ export async function sendMessage({ const project = getProject(session.project_id); if (!project) throw new Error("Project not found"); - // Ensure session artifact directory exists - const sessionDir = path.join(project.path, getSessionArtifactDir(session.id)); + // Ensure session artifact directory exists in global storage + const sessionDir = getSessionDir(session.project_id, session.id); ensureDir(sessionDir); const phaseConfig = getPhaseConfig( @@ -100,22 +112,22 @@ export function advancePhase(session: Session): Phase | null { } /** - * Get the artifact path for a session and phase + * Get the artifact path for a session and phase (in global storage) */ export function getArtifactPath(session: Session): string { const filename = getArtifactFilename(session.phase as Phase); - return path.join(getSessionArtifactDir(session.id), filename); + return path.join(getSessionDir(session.project_id, session.id), filename); } /** - * Read an artifact file for a session + * Read an artifact file for a session (from global storage) */ export function readSessionArtifact( - projectPath: string, + projectId: string, sessionId: string, filename: string ): string | null { - const filePath = path.join(projectPath, getSessionArtifactDir(sessionId), filename); + const filePath = path.join(getSessionDir(projectId, sessionId), filename); if (fs.existsSync(filePath)) { return fs.readFileSync(filePath, "utf-8"); } @@ -123,15 +135,15 @@ export function readSessionArtifact( } /** - * Write an artifact file for a session + * Write an artifact file for a session (to global storage) */ export function writeSessionArtifact( - projectPath: string, + projectId: string, sessionId: string, filename: string, content: string ): void { - const dir = path.join(projectPath, getSessionArtifactDir(sessionId)); + const dir = getSessionDir(projectId, sessionId); ensureDir(dir); fs.writeFileSync(path.join(dir, filename), content, "utf-8"); } @@ -156,37 +168,10 @@ export function writeClaudeMd(projectPath: string, content: string): void { } /** - * Read an artifact file from the project's .claude-flow directory (legacy path) - */ -export function readArtifact( - projectPath: string, - filename: string -): string | null { - const filePath = path.join(projectPath, ".claude-flow", filename); - if (fs.existsSync(filePath)) { - return fs.readFileSync(filePath, "utf-8"); - } - return null; -} - -/** - * Write an artifact file to the project's .claude-flow directory (legacy path) - */ -export function writeArtifact( - projectPath: string, - filename: string, - content: string -): void { - const dir = path.join(projectPath, ".claude-flow"); - ensureDir(dir); - fs.writeFileSync(path.join(dir, filename), content, "utf-8"); -} - -/** - * Clear session artifacts + * Clear session artifacts from global storage */ -export function clearSessionArtifacts(projectPath: string, sessionId: string): void { - const dir = path.join(projectPath, getSessionArtifactDir(sessionId)); +export function clearSessionArtifacts(projectId: string, sessionId: string): void { + const dir = getSessionDir(projectId, sessionId); if (fs.existsSync(dir)) { fs.rmSync(dir, { recursive: true, force: true }); } diff --git a/src/main/claude/phases.ts b/src/main/claude/phases.ts index 6678c08..f1df719 100644 --- a/src/main/claude/phases.ts +++ b/src/main/claude/phases.ts @@ -10,9 +10,9 @@ export interface PhaseConfig { initialMessage: string; } -// Get session-specific artifact path +// Get session-specific artifact path (relative to ~/.claude-flow/) export function getSessionArtifactDir(sessionId: string): string { - return `.claude-flow/sessions/${sessionId}`; + return `sessions/${sessionId}`; } export function getArtifactPath(phase: Phase, sessionId: string): string { @@ -30,7 +30,7 @@ export const phaseConfigs: Record = { systemPrompt: `You are in RESEARCH mode. Your ONLY job is to understand the codebase. CRITICAL RULES: -1. You MUST write ALL findings to \`.claude-flow/sessions/{sessionId}/research.md\` — this is your PRIMARY output +1. You MUST write ALL findings to the session research.md — this is your PRIMARY output 2. DO NOT just respond in chat. The document viewer shows research.md, so write there. 3. DO NOT suggest moving to planning or implementation 4. DO NOT ask "are you ready to implement?" or similar @@ -38,16 +38,15 @@ CRITICAL RULES: 6. The user controls phase transitions via UI buttons — never prompt them about it CONTEXT: -- You are in a git worktree at \`.claude-flow/worktrees/{sessionId}/\` -- Read CLAUDE.md in the project root for shared codebase overview -- If CLAUDE.md doesn't exist, create it with your initial findings +- Read CLAUDE.md in the project root (if it exists) for codebase overview - This file contains general architecture info shared across all sessions +- If CLAUDE.md doesn't exist, create it with your initial findings WORKFLOW: 1. Read CLAUDE.md (create at project root if missing) 2. Ask what to research (if unclear) 3. Read files thoroughly using Read, Glob, Grep -4. Write findings to \`.claude-flow/sessions/{sessionId}/research.md\` +4. Write findings to session research.md 5. Update CLAUDE.md with any new general insights worth sharing FORMAT for research.md: @@ -70,7 +69,7 @@ FORMAT for research.md: [Things that need clarification] \`\`\` -Remember: Your output goes in \`.claude-flow/sessions/{sessionId}/research.md\`, not chat. Chat is for clarifying questions only.`, +Remember: Your output goes in research.md, not chat. Chat is for clarifying questions only.`, }, plan: { @@ -81,7 +80,7 @@ Remember: Your output goes in \`.claude-flow/sessions/{sessionId}/research.md\`, systemPrompt: `You are in PLANNING mode. Your ONLY job is to create an implementation plan. CRITICAL RULES: -1. You MUST write the plan to \`.claude-flow/sessions/{sessionId}/plan.md\` — this is your PRIMARY output +1. You MUST write the plan to session plan.md — this is your PRIMARY output 2. DO NOT just respond in chat. The document viewer shows plan.md, so write there. 3. DO NOT implement anything — no code changes to source files 4. DO NOT ask "should I start implementing?" or similar @@ -89,14 +88,13 @@ CRITICAL RULES: 6. Base your plan on the session research.md and CLAUDE.md CONTEXT: -- You are in a git worktree at \`.claude-flow/worktrees/{sessionId}/\` - Read CLAUDE.md at project root for codebase overview -- Read \`.claude-flow/sessions/{sessionId}/research.md\` for this specific task +- Read the session research.md to understand the specific task WORKFLOW: 1. Read CLAUDE.md for codebase overview 2. Read the session research.md to understand the specific task -3. Write a detailed plan to \`.claude-flow/sessions/{sessionId}/plan.md\` +3. Write a detailed plan to session plan.md 4. Include specific code snippets showing proposed changes 5. Make the plan detailed enough that implementation is mechanical @@ -134,47 +132,30 @@ FORMAT for plan.md: When the user adds annotations to plan.md and clicks Review, address each annotation and update the document. -Remember: Your output goes in \`.claude-flow/sessions/{sessionId}/plan.md\`, not chat. Chat is for clarifying questions only.`, +Remember: Your output goes in plan.md, not chat. Chat is for clarifying questions only.`, }, implement: { permissionMode: "acceptEdits", tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"], initialMessage: - "Starting implementation. I'll follow the plan exactly, commit as I go, and mark tasks complete.", + "Starting implementation. I'll follow the plan exactly and mark tasks complete as I go.", systemPrompt: `You are in IMPLEMENTATION mode. Execute the approved plan. CRITICAL RULES: -1. Read \`.claude-flow/sessions/{sessionId}/plan.md\` and follow it exactly +1. Read session plan.md and follow it exactly 2. Mark tasks complete in plan.md as you finish them: - [ ] → - [x] 3. DO NOT deviate from the plan without asking 4. Run tests/typecheck if available -5. Make git commits as you complete logical chunks of work -6. Stop and ask if you encounter issues not covered by the plan - -CONTEXT: -- You are in a git worktree at \`.claude-flow/worktrees/{sessionId}/\` -- This is an isolated branch: \`claude-flow/{sessionId}\` -- Your commits will not affect the main branch until merged -- The user can review your work in this worktree before accepting +5. Stop and ask if you encounter issues not covered by the plan WORKFLOW: -1. Read \`.claude-flow/sessions/{sessionId}/plan.md\` +1. Read session plan.md 2. Execute each task in order 3. Update plan.md to mark tasks complete -4. Make git commits with clear messages as you finish chunks -5. Continue until all tasks are done - -COMMIT GUIDELINES: -- Commit after completing logical units of work -- Use clear commit messages (e.g., "Add user authentication middleware") -- Don't commit broken or incomplete code -- Update CLAUDE.md at project root if you discover important architecture info - -When complete, summarize what was done and tell the user how to review: -- The work is in worktree: \`.claude-flow/worktrees/{sessionId}/\` -- Branch: \`claude-flow/{sessionId}\` -- They can review, then merge or discard as needed`, +4. Continue until all tasks are done + +When complete, summarize what was done and any follow-up tasks.`, }, }; -- cgit v1.2.3