diff options
| author | Clawd <ai@clawd.bot> | 2026-02-28 18:46:11 -0800 |
|---|---|---|
| committer | Clawd <ai@clawd.bot> | 2026-02-28 18:46:11 -0800 |
| commit | 3ac34530578b9a6f59bcea6b5aeefd97eb03d588 (patch) | |
| tree | 099fe4a4788c5dd5997d1f16f5d2db917eda86d0 /src/main/claude/index.ts | |
| parent | de242df9cbe7dfe483f59f9b25e980727baa4c11 (diff) | |
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
Diffstat (limited to 'src/main/claude/index.ts')
| -rw-r--r-- | src/main/claude/index.ts | 65 |
1 files changed, 25 insertions, 40 deletions
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"; | |||
| 6 | import { updateSession } from "../db/sessions"; | 6 | import { updateSession } from "../db/sessions"; |
| 7 | import fs from "node:fs"; | 7 | import fs from "node:fs"; |
| 8 | import path from "node:path"; | 8 | import path from "node:path"; |
| 9 | import os from "node:os"; | ||
| 9 | 10 | ||
| 10 | // Track active queries by session ID | 11 | // Track active queries by session ID |
| 11 | const activeQueries = new Map<string, Query>(); | 12 | const activeQueries = new Map<string, Query>(); |
| 12 | 13 | ||
| 14 | // Global storage in home directory | ||
| 15 | const GLOBAL_CLAUDE_FLOW_DIR = path.join(os.homedir(), ".claude-flow"); | ||
| 16 | |||
| 13 | function ensureDir(dirPath: string): void { | 17 | function ensureDir(dirPath: string): void { |
| 14 | if (!fs.existsSync(dirPath)) { | 18 | if (!fs.existsSync(dirPath)) { |
| 15 | fs.mkdirSync(dirPath, { recursive: true }); | 19 | fs.mkdirSync(dirPath, { recursive: true }); |
| 16 | } | 20 | } |
| 17 | } | 21 | } |
| 18 | 22 | ||
| 23 | function getProjectDir(projectId: string): string { | ||
| 24 | return path.join(GLOBAL_CLAUDE_FLOW_DIR, "projects", projectId); | ||
| 25 | } | ||
| 26 | |||
| 27 | function getSessionDir(projectId: string, sessionId: string): string { | ||
| 28 | return path.join(getProjectDir(projectId), "sessions", sessionId); | ||
| 29 | } | ||
| 30 | |||
| 19 | export interface SendMessageOptions { | 31 | export interface SendMessageOptions { |
| 20 | session: Session; | 32 | session: Session; |
| 21 | message: string; | 33 | message: string; |
| @@ -30,8 +42,8 @@ export async function sendMessage({ | |||
| 30 | const project = getProject(session.project_id); | 42 | const project = getProject(session.project_id); |
| 31 | if (!project) throw new Error("Project not found"); | 43 | if (!project) throw new Error("Project not found"); |
| 32 | 44 | ||
| 33 | // Ensure session artifact directory exists | 45 | // Ensure session artifact directory exists in global storage |
| 34 | const sessionDir = path.join(project.path, getSessionArtifactDir(session.id)); | 46 | const sessionDir = getSessionDir(session.project_id, session.id); |
| 35 | ensureDir(sessionDir); | 47 | ensureDir(sessionDir); |
| 36 | 48 | ||
| 37 | const phaseConfig = getPhaseConfig( | 49 | const phaseConfig = getPhaseConfig( |
| @@ -100,22 +112,22 @@ export function advancePhase(session: Session): Phase | null { | |||
| 100 | } | 112 | } |
| 101 | 113 | ||
| 102 | /** | 114 | /** |
| 103 | * Get the artifact path for a session and phase | 115 | * Get the artifact path for a session and phase (in global storage) |
| 104 | */ | 116 | */ |
| 105 | export function getArtifactPath(session: Session): string { | 117 | export function getArtifactPath(session: Session): string { |
| 106 | const filename = getArtifactFilename(session.phase as Phase); | 118 | const filename = getArtifactFilename(session.phase as Phase); |
| 107 | return path.join(getSessionArtifactDir(session.id), filename); | 119 | return path.join(getSessionDir(session.project_id, session.id), filename); |
| 108 | } | 120 | } |
| 109 | 121 | ||
| 110 | /** | 122 | /** |
| 111 | * Read an artifact file for a session | 123 | * Read an artifact file for a session (from global storage) |
| 112 | */ | 124 | */ |
| 113 | export function readSessionArtifact( | 125 | export function readSessionArtifact( |
| 114 | projectPath: string, | 126 | projectId: string, |
| 115 | sessionId: string, | 127 | sessionId: string, |
| 116 | filename: string | 128 | filename: string |
| 117 | ): string | null { | 129 | ): string | null { |
| 118 | const filePath = path.join(projectPath, getSessionArtifactDir(sessionId), filename); | 130 | const filePath = path.join(getSessionDir(projectId, sessionId), filename); |
| 119 | if (fs.existsSync(filePath)) { | 131 | if (fs.existsSync(filePath)) { |
| 120 | return fs.readFileSync(filePath, "utf-8"); | 132 | return fs.readFileSync(filePath, "utf-8"); |
| 121 | } | 133 | } |
| @@ -123,15 +135,15 @@ export function readSessionArtifact( | |||
| 123 | } | 135 | } |
| 124 | 136 | ||
| 125 | /** | 137 | /** |
| 126 | * Write an artifact file for a session | 138 | * Write an artifact file for a session (to global storage) |
| 127 | */ | 139 | */ |
| 128 | export function writeSessionArtifact( | 140 | export function writeSessionArtifact( |
| 129 | projectPath: string, | 141 | projectId: string, |
| 130 | sessionId: string, | 142 | sessionId: string, |
| 131 | filename: string, | 143 | filename: string, |
| 132 | content: string | 144 | content: string |
| 133 | ): void { | 145 | ): void { |
| 134 | const dir = path.join(projectPath, getSessionArtifactDir(sessionId)); | 146 | const dir = getSessionDir(projectId, sessionId); |
| 135 | ensureDir(dir); | 147 | ensureDir(dir); |
| 136 | fs.writeFileSync(path.join(dir, filename), content, "utf-8"); | 148 | fs.writeFileSync(path.join(dir, filename), content, "utf-8"); |
| 137 | } | 149 | } |
| @@ -156,37 +168,10 @@ export function writeClaudeMd(projectPath: string, content: string): void { | |||
| 156 | } | 168 | } |
| 157 | 169 | ||
| 158 | /** | 170 | /** |
| 159 | * Read an artifact file from the project's .claude-flow directory (legacy path) | 171 | * Clear session artifacts from global storage |
| 160 | */ | ||
| 161 | export function readArtifact( | ||
| 162 | projectPath: string, | ||
| 163 | filename: string | ||
| 164 | ): string | null { | ||
| 165 | const filePath = path.join(projectPath, ".claude-flow", filename); | ||
| 166 | if (fs.existsSync(filePath)) { | ||
| 167 | return fs.readFileSync(filePath, "utf-8"); | ||
| 168 | } | ||
| 169 | return null; | ||
| 170 | } | ||
| 171 | |||
| 172 | /** | ||
| 173 | * Write an artifact file to the project's .claude-flow directory (legacy path) | ||
| 174 | */ | ||
| 175 | export function writeArtifact( | ||
| 176 | projectPath: string, | ||
| 177 | filename: string, | ||
| 178 | content: string | ||
| 179 | ): void { | ||
| 180 | const dir = path.join(projectPath, ".claude-flow"); | ||
| 181 | ensureDir(dir); | ||
| 182 | fs.writeFileSync(path.join(dir, filename), content, "utf-8"); | ||
| 183 | } | ||
| 184 | |||
| 185 | /** | ||
| 186 | * Clear session artifacts | ||
| 187 | */ | 172 | */ |
| 188 | export function clearSessionArtifacts(projectPath: string, sessionId: string): void { | 173 | export function clearSessionArtifacts(projectId: string, sessionId: string): void { |
| 189 | const dir = path.join(projectPath, getSessionArtifactDir(sessionId)); | 174 | const dir = getSessionDir(projectId, sessionId); |
| 190 | if (fs.existsSync(dir)) { | 175 | if (fs.existsSync(dir)) { |
| 191 | fs.rmSync(dir, { recursive: true, force: true }); | 176 | fs.rmSync(dir, { recursive: true, force: true }); |
| 192 | } | 177 | } |
