1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
import { contextBridge, ipcRenderer, type IpcRendererEvent } from "electron";
import type { SDKMessage } from "@anthropic-ai/claude-agent-sdk";
import type { Project } from "./db/projects";
import type { Session, Message } from "./db/sessions";
import type { Phase, UserPermissionMode } from "./claude/phases";
export interface ClaudeFlowAPI {
// Projects
listProjects: () => Promise<Project[]>;
createProject: (name: string, path: string) => Promise<Project>;
deleteProject: (id: string) => Promise<void>;
// Sessions
listSessions: (projectId: string) => Promise<Session[]>;
createSession: (projectId: string, name: string) => Promise<Session>;
deleteSession: (id: string) => Promise<void>;
getSession: (id: string) => Promise<Session | undefined>;
renameSession: (id: string, name: string) => Promise<void>;
// Messages
listMessages: (sessionId: string) => Promise<Message[]>;
// Chat
sendMessage: (sessionId: string, message: string) => Promise<void>;
interruptSession: (sessionId: string) => Promise<void>;
// Workflow
triggerReview: (sessionId: string) => Promise<void>;
advancePhase: (sessionId: string) => Promise<{ phase: Phase; git_branch: string | null } | null>;
setPermissionMode: (
sessionId: string,
mode: UserPermissionMode
) => Promise<void>;
// Session Artifacts (stored in ~/.claude-flow/)
readSessionArtifact: (
projectId: string,
sessionId: string,
filename: string
) => Promise<string | null>;
writeSessionArtifact: (
projectId: string,
sessionId: string,
filename: string,
content: string
) => Promise<void>;
// CLAUDE.md (stored in project)
readClaudeMd: (projectPath: string) => Promise<string | null>;
writeClaudeMd: (projectPath: string, content: string) => Promise<void>;
// Events
onClaudeMessage: (
callback: (sessionId: string, message: SDKMessage) => void
) => () => void;
// Dialogs
selectDirectory: () => Promise<string | null>;
}
const api: ClaudeFlowAPI = {
// Projects
listProjects: () => ipcRenderer.invoke("projects:list"),
createProject: (name, path) =>
ipcRenderer.invoke("projects:create", name, path),
deleteProject: (id) => ipcRenderer.invoke("projects:delete", id),
// Sessions
listSessions: (projectId) => ipcRenderer.invoke("sessions:list", projectId),
createSession: (projectId, name) =>
ipcRenderer.invoke("sessions:create", projectId, name),
deleteSession: (id) => ipcRenderer.invoke("sessions:delete", id),
getSession: (id) => ipcRenderer.invoke("sessions:get", id),
renameSession: (id, name) => ipcRenderer.invoke("sessions:rename", id, name),
// Messages
listMessages: (sessionId) => ipcRenderer.invoke("messages:list", sessionId),
// Chat
sendMessage: (sessionId, message) =>
ipcRenderer.invoke("chat:send", sessionId, message),
interruptSession: (sessionId) =>
ipcRenderer.invoke("chat:interrupt", sessionId),
// Workflow
triggerReview: (sessionId) => ipcRenderer.invoke("workflow:review", sessionId),
advancePhase: (sessionId) => ipcRenderer.invoke("workflow:advance", sessionId),
setPermissionMode: (sessionId, mode) =>
ipcRenderer.invoke("workflow:setPermissionMode", sessionId, mode),
// Session Artifacts (stored in ~/.claude-flow/)
readSessionArtifact: (projectId, sessionId, filename) =>
ipcRenderer.invoke("artifact:readSession", projectId, sessionId, filename),
writeSessionArtifact: (projectId, sessionId, filename, content) =>
ipcRenderer.invoke("artifact:writeSession", projectId, sessionId, filename, content),
// CLAUDE.md (stored in project)
readClaudeMd: (projectPath) => ipcRenderer.invoke("claudemd:read", projectPath),
writeClaudeMd: (projectPath, content) =>
ipcRenderer.invoke("claudemd:write", projectPath, content),
// Events
onClaudeMessage: (callback) => {
const handler = (
_: IpcRendererEvent,
sessionId: string,
message: SDKMessage
) => callback(sessionId, message);
ipcRenderer.on("claude:message", handler);
return () => ipcRenderer.removeListener("claude:message", handler);
},
// Dialogs
selectDirectory: async () => {
const result = await ipcRenderer.invoke("dialog:selectDirectory");
return result;
},
};
contextBridge.exposeInMainWorld("api", api);
// Type declaration for renderer
declare global {
interface Window {
api: ClaudeFlowAPI;
}
}
|