forked from doctly/switchboard
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpreload.js
More file actions
166 lines (154 loc) · 9.38 KB
/
Copy pathpreload.js
File metadata and controls
166 lines (154 loc) · 9.38 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
const { contextBridge, ipcRenderer, webUtils } = require('electron');
contextBridge.exposeInMainWorld('api', {
// Invoke (request-response)
getStats: () => ipcRenderer.invoke('get-stats'),
getStatsFromDb: () => ipcRenderer.invoke('get-stats-from-db'),
refreshStats: () => ipcRenderer.invoke('refresh-stats'),
getUsage: () => ipcRenderer.invoke('get-usage'),
getMemories: () => ipcRenderer.invoke('get-memories'),
readMemory: (filePath) => ipcRenderer.invoke('read-memory', filePath),
saveMemory: (filePath, content) => ipcRenderer.invoke('save-memory', filePath, content),
getWorkFiles: () => ipcRenderer.invoke('get-work-files'),
readWorkFile: (filePath) => ipcRenderer.invoke('read-work-file', filePath),
deleteWorkFile: (filePath) => ipcRenderer.invoke('delete-work-file', filePath),
getProjects: (showArchived) => ipcRenderer.invoke('get-projects', showArchived),
rebuildCache: () => ipcRenderer.invoke('rebuild-cache'),
getActiveSessions: () => ipcRenderer.invoke('get-active-sessions'),
getActiveTerminals: () => ipcRenderer.invoke('get-active-terminals'),
stopSession: (id) => ipcRenderer.invoke('stop-session', id),
// see .ai/contexts/session-state.md ("The two lifecycle verbs: detach and stop")
remoteStopSession: (alias, sessionId) => ipcRenderer.invoke('remote-stop-session', { alias, sessionId }),
toggleStar: (id) => ipcRenderer.invoke('toggle-star', id),
renameSession: (id, name) => ipcRenderer.invoke('rename-session', id, name),
archiveSession: (id, archived) => ipcRenderer.invoke('archive-session', id, archived),
deleteSession: (id) => ipcRenderer.invoke('delete-session', id),
deleteSessionPreview: (id) => ipcRenderer.invoke('delete-session-preview', id),
// initialSize: { cols, rows } measured by the renderer before the spawn, so
// the PTY never runs against a placeholder geometry. May be null.
openTerminal: (id, projectPath, isNew, sessionOptions, initialSize) => ipcRenderer.invoke('open-terminal', id, projectPath, isNew, sessionOptions, initialSize),
search: (type, query, titleOnly) => ipcRenderer.invoke('search', type, query, titleOnly),
readSessionJsonl: (sessionId) => ipcRenderer.invoke('read-session-jsonl', sessionId),
readSubagentJsonl: (parentSessionId, agentId) => ipcRenderer.invoke('read-subagent-jsonl', parentSessionId, agentId),
listSubagents: (parentSessionId) => ipcRenderer.invoke('list-subagents', parentSessionId),
startSubagentWatch: (parentSessionId, agentId) => ipcRenderer.invoke('start-subagent-watch', parentSessionId, agentId),
stopSubagentWatch: (watchId) => ipcRenderer.invoke('stop-subagent-watch', watchId),
// see .ai/contexts/changes-view.md
gitChangesStatus: (sessionId) => ipcRenderer.invoke('git-changes-status', sessionId),
gitChangesDiff: (sessionId, filePath, staged) => ipcRenderer.invoke('git-changes-diff', sessionId, filePath, staged),
// Settings
getSetting: (key) => ipcRenderer.invoke('get-setting', key),
setSetting: (key, value) => ipcRenderer.invoke('set-setting', key, value),
deleteSetting: (key) => ipcRenderer.invoke('delete-setting', key),
getEffectiveSettings: (projectPath) => ipcRenderer.invoke('get-effective-settings', projectPath),
remoteHostsApply: () => ipcRenderer.invoke('remote-hosts-apply'),
remoteHostsRefresh: () => ipcRenderer.invoke('remote-hosts-refresh'),
remoteHostRefresh: (alias) => ipcRenderer.invoke('remote-host-refresh', alias),
getScheduleCreatorCommand: () => ipcRenderer.invoke('get-schedule-creator-command'),
createScheduleSession: (projectPath) => ipcRenderer.invoke('create-schedule-session', projectPath),
runScheduleNow: (filePath) => ipcRenderer.invoke('run-schedule-now', filePath),
getShellProfiles: () => ipcRenderer.invoke('get-shell-profiles'),
browseFolder: () => ipcRenderer.invoke('browse-folder'),
addProject: (projectPath) => ipcRenderer.invoke('add-project', projectPath),
removeProject: (projectPath, folderKey) => ipcRenderer.invoke('remove-project', projectPath, folderKey),
remapProject: (oldPath, newPath) => ipcRenderer.invoke('remap-project', oldPath, newPath),
deleteWorktree: (worktreePath) => ipcRenderer.invoke('delete-worktree', worktreePath),
worktreeStatus: (worktreePath) => ipcRenderer.invoke('worktree-status', worktreePath),
openExternal: (url) => ipcRenderer.invoke('open-external', url),
openPath: (filePath) => ipcRenderer.invoke('open-path', filePath),
toggleFullScreen: () => ipcRenderer.invoke('toggle-full-screen'),
writeClipboard: (text) => ipcRenderer.invoke('clipboard-write-text', text),
readClipboard: () => ipcRenderer.invoke('read-clipboard'),
clipboardHasImage: () => ipcRenderer.invoke('clipboard-has-image'),
// Opt-in activity trace — see docs/activity-trace.md. Main resolves the state
// (activity-trace.js) and passes the startup value as an argument; never
// re-parsed here. Later changes arrive on the onActivityTraceState channel.
activityTraceEnabled: process.argv.includes('--switchboard-activity-trace'),
traceActivity: (cat, sid, fields) => ipcRenderer.send('activity-trace', cat, sid, fields),
getActivityTraceState: () => ipcRenderer.invoke('get-activity-trace-state'),
setActivityTraceEnabled: (enabled) => ipcRenderer.invoke('set-activity-trace-enabled', enabled),
listActivityTraceFiles: () => ipcRenderer.invoke('list-activity-trace-files'),
readActivityTraceFile: (filePath) => ipcRenderer.invoke('read-activity-trace-file', filePath),
deleteActivityTraceFile: (filePath) => ipcRenderer.invoke('delete-activity-trace-file', filePath),
onActivityTraceState: (cb) => ipcRenderer.on('activity-trace-state', (_e, enabled) => cb(enabled)),
// Send (fire-and-forget)
sendInput: (id, data) => ipcRenderer.send('terminal-input', id, data),
resizeTerminal: (id, cols, rows) => ipcRenderer.send('terminal-resize', id, cols, rows),
closeTerminal: (id) => ipcRenderer.send('close-terminal', id),
// Listeners (main → renderer)
onTerminalData: (callback) => {
ipcRenderer.on('terminal-data', (_event, sessionId, data) => callback(sessionId, data));
},
onSessionDetected: (callback) => {
ipcRenderer.on('session-detected', (_event, tempId, realId) => callback(tempId, realId));
},
onProcessExited: (callback) => {
ipcRenderer.on('process-exited', (_event, sessionId, exitCode) => callback(sessionId, exitCode));
},
onTerminalNotification: (callback) => {
ipcRenderer.on('terminal-notification', (_event, sessionId, message) => callback(sessionId, message));
},
onCliBusyState: (callback) => {
ipcRenderer.on('cli-busy-state', (_event, sessionId, busy) => callback(sessionId, busy));
},
onSessionForked: (callback) => {
ipcRenderer.on('session-forked', (_event, oldId, newId) => callback(oldId, newId));
},
onSubagentSpawned: (cb) => ipcRenderer.on('subagent-spawned', (_e, payload) => cb(payload)),
onSubagentCompleted: (cb) => ipcRenderer.on('subagent-completed', (_e, payload) => cb(payload)),
onSubagentWatchEvent: (cb) => ipcRenderer.on('subagent-watch-event', (_e, payload) => cb(payload)),
onProjectsChanged: (callback) => {
ipcRenderer.on('projects-changed', () => callback());
},
onRemoteActivity: (callback) => {
ipcRenderer.on('remote-activity', (_event, payload) => callback(payload));
},
onSessionTranscriptActivity: (callback) => {
ipcRenderer.on('session-transcript-activity', (_event, payload) => callback(payload));
},
onStatusUpdate: (callback) => {
ipcRenderer.on('status-update', (_event, text, type) => callback(text, type));
},
onIndexingProgress: (callback) => {
ipcRenderer.on('indexing-progress', (_event, payload) => callback(payload));
},
onFullScreenChanged: (callback) => {
ipcRenderer.on('full-screen-changed', (_event, isFullScreen) => callback(isFullScreen));
},
// File drag-and-drop
getPathForFile: (file) => webUtils.getPathForFile(file),
// Platform
platform: process.platform,
// App version
getAppVersion: () => ipcRenderer.invoke('get-app-version'),
// Auto-updater
updaterCheck: () => ipcRenderer.invoke('updater-check'),
updaterDownload: () => ipcRenderer.invoke('updater-download'),
updaterInstall: () => ipcRenderer.invoke('updater-install'),
onUpdaterEvent: (callback) => {
ipcRenderer.on('updater-event', (_event, type, data) => callback(type, data));
},
// MCP bridge (main → renderer)
onMcpOpenDiff: (callback) => {
ipcRenderer.on('mcp-open-diff', (_event, sessionId, diffId, data) => callback(sessionId, diffId, data));
},
onMcpOpenFile: (callback) => {
ipcRenderer.on('mcp-open-file', (_event, sessionId, data) => callback(sessionId, data));
},
onMcpCloseAllDiffs: (callback) => {
ipcRenderer.on('mcp-close-all-diffs', (_event, sessionId) => callback(sessionId));
},
onMcpCloseTab: (callback) => {
ipcRenderer.on('mcp-close-tab', (_event, sessionId, diffId) => callback(sessionId, diffId));
},
// MCP bridge (renderer → main)
mcpDiffResponse: (sessionId, diffId, action, editedContent) => {
ipcRenderer.send('mcp-diff-response', sessionId, diffId, action, editedContent);
},
readFileForPanel: (filePath) => ipcRenderer.invoke('read-file-for-panel', filePath),
saveFileForPanel: (filePath, content) => ipcRenderer.invoke('save-file-for-panel', filePath, content),
watchFile: (filePath) => ipcRenderer.invoke('watch-file', filePath),
unwatchFile: (filePath) => ipcRenderer.invoke('unwatch-file', filePath),
onFileChanged: (callback) => {
ipcRenderer.on('file-changed', (_event, filePath) => callback(filePath));
},
});