From 7804c3ea18c7e92a32755b74e4ddb4e847f69e7d Mon Sep 17 00:00:00 2001 From: Lucas Faria Date: Mon, 17 Nov 2025 11:16:53 -0300 Subject: [PATCH] feat: add task directory mapping store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create taskDirectoryStore with localStorage persistence - Support two-level mapping (taskId → dir, repoKey → dir) - Auto-map tasks to existing repo clones - Use existing expandTildePath utility Foundation for PR #3 (directory integration). --- .../task-detail/stores/taskExecutionStore.ts | 5 +- src/renderer/stores/taskDirectoryStore.ts | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/renderer/stores/taskDirectoryStore.ts diff --git a/src/renderer/features/task-detail/stores/taskExecutionStore.ts b/src/renderer/features/task-detail/stores/taskExecutionStore.ts index d77a7ce6..3d3bc45e 100644 --- a/src/renderer/features/task-detail/stores/taskExecutionStore.ts +++ b/src/renderer/features/task-detail/stores/taskExecutionStore.ts @@ -12,6 +12,7 @@ import type { TaskRun, } from "@shared/types"; import { cloneStore } from "@stores/cloneStore"; +import { repositoryWorkspaceStore } from "@stores/repositoryWorkspaceStore"; import { expandTildePath } from "@utils/path"; import { create } from "zustand"; import { persist } from "zustand/middleware"; @@ -504,10 +505,6 @@ export const useTaskExecutionStore = create()( .getState() .startClone(cloneId, task.repository_config, effectiveRepoPath); - const { repositoryWorkspaceStore } = await import( - "@stores/repositoryWorkspaceStore" - ); - try { await repositoryWorkspaceStore .getState() diff --git a/src/renderer/stores/taskDirectoryStore.ts b/src/renderer/stores/taskDirectoryStore.ts new file mode 100644 index 00000000..5bfe033a --- /dev/null +++ b/src/renderer/stores/taskDirectoryStore.ts @@ -0,0 +1,82 @@ +import { expandTildePath } from "@utils/path"; +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +interface TaskDirectoryState { + taskDirectories: Record; + repoDirectories: Record; + getTaskDirectory: (taskId: string, repoKey?: string) => string | null; + setTaskDirectory: (taskId: string, directory: string) => void; + setRepoDirectory: (repoKey: string, directory: string) => void; + clearTaskDirectory: (taskId: string) => void; + clearRepoDirectory: (repoKey: string) => void; +} + +export const useTaskDirectoryStore = create()( + persist( + (set, get) => ({ + taskDirectories: {}, + repoDirectories: {}, + + getTaskDirectory: (taskId: string, repoKey?: string) => { + // 1. Check for direct task mapping + const taskDir = get().taskDirectories[taskId]; + if (taskDir) { + return expandTildePath(taskDir); + } + + // 2. Check for repo mapping (if repoKey provided) + if (repoKey) { + const repoDir = get().repoDirectories[repoKey]; + if (repoDir) { + // Auto-map task to this directory for convenience + get().setTaskDirectory(taskId, repoDir); + return expandTildePath(repoDir); + } + } + + // 3. No mapping found + return null; + }, + + setTaskDirectory: (taskId: string, directory: string) => { + set((state) => ({ + taskDirectories: { + ...state.taskDirectories, + [taskId]: directory, + }, + })); + }, + + setRepoDirectory: (repoKey: string, directory: string) => { + set((state) => ({ + repoDirectories: { + ...state.repoDirectories, + [repoKey]: directory, + }, + })); + }, + + clearTaskDirectory: (taskId: string) => { + set((state) => { + const { [taskId]: _, ...rest } = state.taskDirectories; + return { taskDirectories: rest }; + }); + }, + + clearRepoDirectory: (repoKey: string) => { + set((state) => { + const { [repoKey]: _, ...rest } = state.repoDirectories; + return { repoDirectories: rest }; + }); + }, + }), + { + name: "task-directory-mappings", + partialize: (state) => ({ + taskDirectories: state.taskDirectories, + repoDirectories: state.repoDirectories, + }), + }, + ), +);