aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/preload.ts
blob: 2c228dd1f5feb077ff64102bedffb292555eb020 (plain)
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
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>;

  // 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 | 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),

  // 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;
  }
}