Skip to content

Commit eb783d3

Browse files
committed
feat: add task directory mapping store
- 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).
1 parent ba34212 commit eb783d3

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { expandTildePath } from "@utils/path";
2+
import { create } from "zustand";
3+
import { persist } from "zustand/middleware";
4+
5+
interface TaskDirectoryState {
6+
// Direct task-to-directory mappings
7+
taskDirectories: Record<string, string>;
8+
9+
// Repository-to-directory mappings (enables repo reuse across tasks)
10+
repoDirectories: Record<string, string>;
11+
12+
// Get directory for a task (checks task mapping first, then repo mapping)
13+
getTaskDirectory: (taskId: string, repoKey?: string) => string | null;
14+
15+
// Set directory for a specific task
16+
setTaskDirectory: (taskId: string, directory: string) => void;
17+
18+
// Set directory for a repository (shared across tasks)
19+
setRepoDirectory: (repoKey: string, directory: string) => void;
20+
21+
// Remove task directory mapping
22+
clearTaskDirectory: (taskId: string) => void;
23+
24+
// Remove repository directory mapping
25+
clearRepoDirectory: (repoKey: string) => void;
26+
}
27+
28+
export const useTaskDirectoryStore = create<TaskDirectoryState>()(
29+
persist(
30+
(set, get) => ({
31+
taskDirectories: {},
32+
repoDirectories: {},
33+
34+
getTaskDirectory: (taskId: string, repoKey?: string) => {
35+
// 1. Check for direct task mapping
36+
const taskDir = get().taskDirectories[taskId];
37+
if (taskDir) {
38+
return expandTildePath(taskDir);
39+
}
40+
41+
// 2. Check for repo mapping (if repoKey provided)
42+
if (repoKey) {
43+
const repoDir = get().repoDirectories[repoKey];
44+
if (repoDir) {
45+
// Auto-map task to this directory for convenience
46+
get().setTaskDirectory(taskId, repoDir);
47+
return expandTildePath(repoDir);
48+
}
49+
}
50+
51+
// 3. No mapping found
52+
return null;
53+
},
54+
55+
setTaskDirectory: (taskId: string, directory: string) => {
56+
set((state) => ({
57+
taskDirectories: {
58+
...state.taskDirectories,
59+
[taskId]: directory,
60+
},
61+
}));
62+
},
63+
64+
setRepoDirectory: (repoKey: string, directory: string) => {
65+
set((state) => ({
66+
repoDirectories: {
67+
...state.repoDirectories,
68+
[repoKey]: directory,
69+
},
70+
}));
71+
},
72+
73+
clearTaskDirectory: (taskId: string) => {
74+
set((state) => {
75+
const { [taskId]: _, ...rest } = state.taskDirectories;
76+
return { taskDirectories: rest };
77+
});
78+
},
79+
80+
clearRepoDirectory: (repoKey: string) => {
81+
set((state) => {
82+
const { [repoKey]: _, ...rest } = state.repoDirectories;
83+
return { repoDirectories: rest };
84+
});
85+
},
86+
}),
87+
{
88+
name: "task-directory-mappings",
89+
partialize: (state) => ({
90+
taskDirectories: state.taskDirectories,
91+
repoDirectories: state.repoDirectories,
92+
}),
93+
},
94+
),
95+
);

0 commit comments

Comments
 (0)