copilotoffice 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,481 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+
25
+ // electron/main.ts
26
+ var import_electron2 = require("electron");
27
+ var path2 = __toESM(require("path"));
28
+ var fs = __toESM(require("fs"));
29
+ var import_child_process2 = require("child_process");
30
+
31
+ // electron/terminal/ipc-relay.ts
32
+ var import_electron = require("electron");
33
+ var import_child_process = require("child_process");
34
+ var crypto = __toESM(require("crypto"));
35
+ var path = __toESM(require("path"));
36
+ var TerminalRelay = class {
37
+ constructor(getWindow) {
38
+ this.server = null;
39
+ this.pendingRequests = /* @__PURE__ */ new Map();
40
+ /** True while a deliberate shutdown→respawn is in progress (prevents double-spawn). */
41
+ this.shuttingDown = false;
42
+ /** Requests that arrived while the server was not connected. Flushed on ready. */
43
+ this.queuedRequests = [];
44
+ this.getWindow = getWindow;
45
+ }
46
+ // ── Server Lifecycle ──────────────────────────────────────────
47
+ spawnServer(distDir) {
48
+ return new Promise((resolve, reject) => {
49
+ const serverPath = path.join(distDir, "terminal", "server.js");
50
+ console.log("[Relay] Forking terminal server:", serverPath);
51
+ this.server = (0, import_child_process.fork)(serverPath, [], {
52
+ cwd: process.cwd(),
53
+ stdio: ["pipe", "inherit", "inherit", "ipc"]
54
+ });
55
+ const readyTimeout = setTimeout(() => {
56
+ reject(new Error("Terminal server did not send ready in time"));
57
+ }, 15e3);
58
+ this.server.on("message", (msg) => {
59
+ this.handleServerMessage(msg, readyTimeout, resolve);
60
+ });
61
+ this.server.on("exit", (code, signal) => {
62
+ console.error(`[Relay] Terminal server exited (code=${code}, signal=${signal})`);
63
+ clearTimeout(readyTimeout);
64
+ this.pendingRequests.forEach(
65
+ (cb) => cb({ success: false, error: "Terminal server crashed" })
66
+ );
67
+ this.pendingRequests.clear();
68
+ this.server = null;
69
+ if (this.shuttingDown) {
70
+ console.log("[Relay] Deliberate shutdown \u2014 skipping auto-respawn");
71
+ return;
72
+ }
73
+ const win = this.getWindow();
74
+ if (win && !win.isDestroyed()) {
75
+ console.log("[Relay] Respawning terminal server...");
76
+ this.spawnServer(distDir).catch(
77
+ (e) => console.error("[Relay] Failed to respawn:", e)
78
+ );
79
+ }
80
+ });
81
+ });
82
+ }
83
+ shutdown() {
84
+ this.shuttingDown = true;
85
+ const oldServer = this.server;
86
+ this.server = null;
87
+ if (!oldServer) {
88
+ this.pendingRequests.clear();
89
+ this.queuedRequests = [];
90
+ return Promise.resolve();
91
+ }
92
+ oldServer.removeAllListeners("exit");
93
+ oldServer.removeAllListeners("message");
94
+ if (oldServer.connected) {
95
+ try {
96
+ oldServer.send({ type: "shutdown" });
97
+ } catch {
98
+ }
99
+ }
100
+ this.pendingRequests.forEach(
101
+ (cb) => cb({ success: false, error: "Terminal server shut down" })
102
+ );
103
+ this.pendingRequests.clear();
104
+ this.queuedRequests = [];
105
+ const oldPid = oldServer.pid;
106
+ return new Promise((resolve) => {
107
+ const onExit = () => {
108
+ clearTimeout(timeout);
109
+ resolve();
110
+ };
111
+ oldServer.once("exit", onExit);
112
+ const timeout = setTimeout(() => {
113
+ oldServer.removeListener("exit", onExit);
114
+ if (oldPid) {
115
+ try {
116
+ process.kill(oldPid, 0);
117
+ console.log(`[Relay] Server PID ${oldPid} still alive after timeout \u2014 force killing`);
118
+ if (process.platform === "win32") {
119
+ (0, import_child_process.execSync)(`taskkill /T /F /PID ${oldPid}`, { stdio: "ignore" });
120
+ } else {
121
+ process.kill(oldPid, "SIGKILL");
122
+ }
123
+ } catch {
124
+ }
125
+ }
126
+ resolve();
127
+ }, 3e3);
128
+ });
129
+ }
130
+ // ── Internal Helpers ─────────────────────────────────────────
131
+ send(msg) {
132
+ if (this.server?.connected) {
133
+ this.server.send(msg);
134
+ }
135
+ }
136
+ request(msg) {
137
+ if (!this.server?.connected) {
138
+ console.log(`[Relay] Server not connected \u2014 queuing request ${msg.type} (${msg.requestId})`);
139
+ return new Promise((resolve) => {
140
+ this.queuedRequests.push({ msg, resolve });
141
+ });
142
+ }
143
+ return new Promise((resolve) => {
144
+ this.pendingRequests.set(msg.requestId, resolve);
145
+ this.send(msg);
146
+ });
147
+ }
148
+ id() {
149
+ return crypto.randomUUID();
150
+ }
151
+ handleServerMessage(msg, readyTimeout, onReady) {
152
+ if (msg.type === "ready") {
153
+ clearTimeout(readyTimeout);
154
+ this.shuttingDown = false;
155
+ console.log("[Relay] Terminal server ready");
156
+ if (this.queuedRequests.length > 0) {
157
+ console.log(`[Relay] Flushing ${this.queuedRequests.length} queued request(s)`);
158
+ for (const queued of this.queuedRequests) {
159
+ this.pendingRequests.set(queued.msg.requestId, queued.resolve);
160
+ this.send(queued.msg);
161
+ }
162
+ this.queuedRequests = [];
163
+ }
164
+ onReady();
165
+ return;
166
+ }
167
+ if (msg.type === "response") {
168
+ const cb = this.pendingRequests.get(msg.requestId);
169
+ if (cb) {
170
+ this.pendingRequests.delete(msg.requestId);
171
+ cb(msg.result);
172
+ }
173
+ return;
174
+ }
175
+ const win = this.getWindow();
176
+ if (!win || win.isDestroyed()) return;
177
+ switch (msg.type) {
178
+ case "terminal-data":
179
+ win.webContents.send("terminal-data", msg.agentId, msg.data);
180
+ break;
181
+ case "terminal-exit":
182
+ win.webContents.send("terminal-exit", msg.agentId, msg.exitCode);
183
+ break;
184
+ case "copilot-event":
185
+ win.webContents.send("copilot-event", msg.agentId, msg.event);
186
+ break;
187
+ case "copilot-tool-start":
188
+ win.webContents.send("copilot-tool-start", msg.agentId, msg.toolName, msg.toolId, msg.status);
189
+ break;
190
+ case "copilot-tool-complete":
191
+ win.webContents.send("copilot-tool-complete", msg.agentId, msg.toolId, msg.success);
192
+ break;
193
+ case "copilot-turn-end":
194
+ win.webContents.send("copilot-turn-end", msg.agentId);
195
+ break;
196
+ case "copilot-turn-start":
197
+ win.webContents.send("copilot-turn-start", msg.agentId);
198
+ break;
199
+ case "copilot-user-message":
200
+ win.webContents.send("copilot-user-message", msg.agentId);
201
+ break;
202
+ case "session-meta-updated":
203
+ win.webContents.send("session-meta-updated", msg.agentId, msg.meta);
204
+ break;
205
+ case "terminal-preload-status":
206
+ win.webContents.send("terminal-preload-status", msg.agentId, msg.status);
207
+ break;
208
+ }
209
+ }
210
+ // ── IPC Handler Registration ──────────────────────────────────
211
+ registerIpc() {
212
+ import_electron.ipcMain.handle(
213
+ "terminal-start",
214
+ (_event, officeId, agentId, workingDir, cols, rows, preseededPrompt) => this.request({ type: "start", requestId: this.id(), officeId, agentId, workingDir, cols, rows, preseededPrompt })
215
+ );
216
+ import_electron.ipcMain.handle(
217
+ "terminal-attach",
218
+ (_event, officeId, agentId) => this.request({ type: "attach", requestId: this.id(), officeId, agentId })
219
+ );
220
+ import_electron.ipcMain.handle("terminal-detach", (_event, officeId, agentId) => {
221
+ this.send({ type: "detach", officeId, agentId });
222
+ return { success: true };
223
+ });
224
+ import_electron.ipcMain.handle(
225
+ "terminal-write",
226
+ (_event, officeId, agentId, data) => this.request({ type: "write", requestId: this.id(), officeId, agentId, data })
227
+ );
228
+ import_electron.ipcMain.handle("terminal-resize", (_event, officeId, agentId, cols, rows) => {
229
+ this.send({ type: "resize", officeId, agentId, cols, rows });
230
+ return { success: true };
231
+ });
232
+ import_electron.ipcMain.handle(
233
+ "terminal-kill",
234
+ (_event, officeId, agentId) => this.request({ type: "kill", requestId: this.id(), officeId, agentId })
235
+ );
236
+ import_electron.ipcMain.handle(
237
+ "terminal-exists",
238
+ (_event, officeId, agentId) => this.request({ type: "exists", requestId: this.id(), officeId, agentId })
239
+ );
240
+ import_electron.ipcMain.handle(
241
+ "terminal-pop-out",
242
+ (_event, officeId, agentId) => this.request({ type: "pop-out", requestId: this.id(), officeId, agentId })
243
+ );
244
+ import_electron.ipcMain.handle(
245
+ "get-session-id",
246
+ (_event, officeId, agentId) => this.request({ type: "get-session-id", requestId: this.id(), officeId, agentId })
247
+ );
248
+ import_electron.ipcMain.handle(
249
+ "reset-all-sessions",
250
+ (_event, officeId) => this.request({ type: "reset-all-sessions", requestId: this.id(), officeId })
251
+ );
252
+ import_electron.ipcMain.handle(
253
+ "terminal-reset-session",
254
+ (_event, officeId, agentId) => this.request({ type: "reset-session", requestId: this.id(), officeId, agentId })
255
+ );
256
+ import_electron.ipcMain.handle(
257
+ "terminal-get-session-history",
258
+ (_event, officeId, agentId) => this.request({ type: "get-session-history", requestId: this.id(), officeId, agentId })
259
+ );
260
+ import_electron.ipcMain.handle(
261
+ "terminal-clear-session-history",
262
+ (_event, officeId, agentId) => this.request({ type: "clear-session-history", requestId: this.id(), officeId, agentId })
263
+ );
264
+ import_electron.ipcMain.handle(
265
+ "list-active-terminals",
266
+ () => this.request({ type: "list-active", requestId: this.id() })
267
+ );
268
+ import_electron.ipcMain.handle(
269
+ "query-agent-statuses",
270
+ (_event, officeId) => this.request({ type: "query-agent-statuses", requestId: this.id(), officeId })
271
+ );
272
+ import_electron.ipcMain.handle(
273
+ "set-session-meta",
274
+ (_event, officeId, agentId, meta) => this.request({ type: "set-session-meta", requestId: this.id(), officeId, agentId, meta })
275
+ );
276
+ import_electron.ipcMain.handle(
277
+ "get-session-meta",
278
+ (_event, officeId, agentId) => this.request({ type: "get-session-meta", requestId: this.id(), officeId, agentId })
279
+ );
280
+ import_electron.ipcMain.handle(
281
+ "get-all-session-meta",
282
+ (_event, officeId) => this.request({ type: "get-all-session-meta", requestId: this.id(), officeId })
283
+ );
284
+ import_electron.ipcMain.handle(
285
+ "create-office-session",
286
+ (_event, officeId) => this.request({ type: "create-office-session", requestId: this.id(), officeId })
287
+ );
288
+ import_electron.ipcMain.handle(
289
+ "delete-office-session",
290
+ (_event, officeId) => this.request({ type: "delete-office-session", requestId: this.id(), officeId })
291
+ );
292
+ import_electron.ipcMain.handle(
293
+ "transfer-session",
294
+ (_event, fromOfficeId, toOfficeId, agentId) => this.request({ type: "transfer-session", requestId: this.id(), fromOfficeId, toOfficeId, agentId })
295
+ );
296
+ }
297
+ };
298
+
299
+ // electron/main.ts
300
+ var OPEN_DEVTOOLS_ON_START = process.env.COPILOT_OFFICE_OPEN_DEVTOOLS !== "0";
301
+ var ENABLE_FILE_WATCHER = process.env.COPILOT_OFFICE_ENABLE_WATCHER !== "0";
302
+ function killOrphanedProcesses() {
303
+ try {
304
+ if (process.platform === "win32") {
305
+ const out = (0, import_child_process2.execSync)(
306
+ `wmic process where "CommandLine like '%COPILOT_OFFICE_PROCESS%'" get ProcessId`,
307
+ { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }
308
+ );
309
+ const pids = out.split(/\r?\n/).map((l) => parseInt(l.trim(), 10)).filter((n) => !isNaN(n) && n !== process.pid);
310
+ if (pids.length > 0) {
311
+ console.log(`[Main] Killing ${pids.length} orphaned COPILOT_OFFICE processes:`, pids);
312
+ for (const pid of pids) {
313
+ try {
314
+ (0, import_child_process2.execSync)(`taskkill /T /F /PID ${pid}`, { stdio: "ignore" });
315
+ } catch {
316
+ }
317
+ }
318
+ }
319
+ } else {
320
+ const out = (0, import_child_process2.execSync)("pgrep -f COPILOT_OFFICE_PROCESS || true", {
321
+ encoding: "utf8",
322
+ stdio: ["pipe", "pipe", "ignore"]
323
+ });
324
+ const pids = out.split(/\r?\n/).map((l) => parseInt(l.trim(), 10)).filter((n) => !isNaN(n) && n !== process.pid);
325
+ if (pids.length > 0) {
326
+ console.log(`[Main] Killing ${pids.length} orphaned COPILOT_OFFICE processes:`, pids);
327
+ for (const pid of pids) {
328
+ try {
329
+ process.kill(pid, "SIGKILL");
330
+ } catch {
331
+ }
332
+ }
333
+ }
334
+ }
335
+ } catch {
336
+ }
337
+ }
338
+ var mainWindow = null;
339
+ var watcherProcess = null;
340
+ var relay = new TerminalRelay(() => mainWindow);
341
+ var pendingHardReload = false;
342
+ function startFileWatcher() {
343
+ const copilotOfficePath = path2.join(process.cwd(), "CopilotOffice");
344
+ if (!fs.existsSync(path2.join(copilotOfficePath, "package.json"))) {
345
+ if (fs.existsSync(path2.join(process.cwd(), "src", "main.ts"))) {
346
+ watcherProcess = (0, import_child_process2.spawn)("npx", ["esbuild", "src/main.ts", "--bundle", "--outfile=dist/game.bundle.js", "--platform=browser", "--format=iife", "--global-name=CopilotOffice", "--watch"], {
347
+ cwd: process.cwd(),
348
+ shell: true,
349
+ stdio: "pipe"
350
+ });
351
+ }
352
+ } else {
353
+ watcherProcess = (0, import_child_process2.spawn)("npx", ["esbuild", "src/main.ts", "--bundle", "--outfile=dist/game.bundle.js", "--platform=browser", "--format=iife", "--global-name=CopilotOffice", "--watch"], {
354
+ cwd: copilotOfficePath,
355
+ shell: true,
356
+ stdio: "pipe"
357
+ });
358
+ }
359
+ if (watcherProcess) {
360
+ watcherProcess.stdout?.on("data", (data) => {
361
+ const msg = data.toString();
362
+ console.log("[Watcher]", msg);
363
+ if (msg.includes("watching") || msg.includes("built")) {
364
+ if (mainWindow && !mainWindow.isDestroyed()) {
365
+ mainWindow.webContents.send("build-complete");
366
+ }
367
+ }
368
+ });
369
+ watcherProcess.stderr?.on("data", (data) => {
370
+ console.error("[Watcher Error]", data.toString());
371
+ });
372
+ console.log("File watcher started");
373
+ }
374
+ }
375
+ function createWindow() {
376
+ mainWindow = new import_electron2.BrowserWindow({
377
+ width: 2560,
378
+ height: 1440,
379
+ title: "Copilot Office",
380
+ webPreferences: {
381
+ preload: path2.join(__dirname, "terminal", "preload.js"),
382
+ contextIsolation: true,
383
+ nodeIntegration: false
384
+ }
385
+ });
386
+ mainWindow.maximize();
387
+ mainWindow.loadFile(path2.join(__dirname, "../../src/index.html"));
388
+ if (OPEN_DEVTOOLS_ON_START) {
389
+ mainWindow.webContents.openDevTools({ mode: "detach" });
390
+ }
391
+ mainWindow.webContents.on("did-start-navigation", (_event, _url, isInPlace) => {
392
+ if (isInPlace && pendingHardReload) {
393
+ console.log("[Main] Hard reload \u2014 restarting terminal server");
394
+ pendingHardReload = false;
395
+ relay.shutdown().then(
396
+ () => relay.spawnServer(__dirname)
397
+ ).catch(
398
+ (e) => console.error("[Main] Failed to respawn after reload:", e)
399
+ );
400
+ } else if (isInPlace) {
401
+ console.log("[Main] Soft reload \u2014 keeping terminal server alive");
402
+ }
403
+ });
404
+ mainWindow.on("closed", () => {
405
+ if (watcherProcess) {
406
+ watcherProcess.kill();
407
+ watcherProcess = null;
408
+ }
409
+ mainWindow = null;
410
+ });
411
+ }
412
+ import_electron2.app.whenReady().then(async () => {
413
+ import_electron2.Menu.setApplicationMenu(null);
414
+ killOrphanedProcesses();
415
+ relay.registerIpc();
416
+ import_electron2.ipcMain.handle("request-hard-reload", () => {
417
+ console.log("[Main] Hard reload requested by renderer");
418
+ pendingHardReload = true;
419
+ return { success: true };
420
+ });
421
+ import_electron2.ipcMain.handle("show-native-notification", (_event, title, body) => {
422
+ if (!import_electron2.Notification.isSupported()) return { success: false };
423
+ const notification = new import_electron2.Notification({ title, body });
424
+ notification.on("click", () => {
425
+ if (mainWindow) {
426
+ if (mainWindow.isMinimized()) mainWindow.restore();
427
+ mainWindow.focus();
428
+ }
429
+ });
430
+ notification.show();
431
+ return { success: true };
432
+ });
433
+ const dataDir = path2.join(process.cwd(), ".data");
434
+ fs.mkdirSync(dataDir, { recursive: true });
435
+ const officesFilePath = path2.join(dataDir, "copilot-offices.json");
436
+ import_electron2.ipcMain.handle("save-offices", (_event, data) => {
437
+ try {
438
+ fs.mkdirSync(dataDir, { recursive: true });
439
+ fs.writeFileSync(officesFilePath, data, "utf8");
440
+ return { success: true };
441
+ } catch (e) {
442
+ console.warn("[Main] Failed to save offices:", e);
443
+ return { success: false, error: String(e) };
444
+ }
445
+ });
446
+ import_electron2.ipcMain.handle("load-offices", () => {
447
+ try {
448
+ if (!fs.existsSync(officesFilePath)) return { success: true, data: null };
449
+ const data = fs.readFileSync(officesFilePath, "utf8");
450
+ return { success: true, data };
451
+ } catch (e) {
452
+ console.warn("[Main] Failed to load offices:", e);
453
+ return { success: false, error: String(e), data: null };
454
+ }
455
+ });
456
+ await relay.spawnServer(__dirname);
457
+ if (ENABLE_FILE_WATCHER) {
458
+ startFileWatcher();
459
+ } else {
460
+ console.log("[Main] File watcher disabled");
461
+ }
462
+ createWindow();
463
+ import_electron2.app.on("activate", () => {
464
+ if (import_electron2.BrowserWindow.getAllWindows().length === 0) createWindow();
465
+ });
466
+ });
467
+ import_electron2.app.on("window-all-closed", () => {
468
+ if (watcherProcess) watcherProcess.kill();
469
+ if (process.platform !== "darwin") import_electron2.app.quit();
470
+ });
471
+ var isShuttingDown = false;
472
+ import_electron2.app.on("before-quit", (event) => {
473
+ if (isShuttingDown) return;
474
+ isShuttingDown = true;
475
+ event.preventDefault();
476
+ console.log("[Main] Awaiting relay shutdown before quit\u2026");
477
+ relay.shutdown().finally(() => {
478
+ console.log("[Main] Relay shutdown complete \u2014 quitting");
479
+ import_electron2.app.quit();
480
+ });
481
+ });
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // electron/preload.ts
17
+ var preload_exports = {};
18
+ module.exports = __toCommonJS(preload_exports);
19
+ var import_electron = require("electron");
20
+ import_electron.contextBridge.exposeInMainWorld("copilotBridge", {
21
+ // Terminal management
22
+ terminalStart: (agentId, workingDir) => {
23
+ return import_electron.ipcRenderer.invoke("terminal-start", agentId, workingDir);
24
+ },
25
+ terminalWrite: (agentId, data) => {
26
+ return import_electron.ipcRenderer.invoke("terminal-write", agentId, data);
27
+ },
28
+ terminalResize: (agentId, cols, rows) => {
29
+ return import_electron.ipcRenderer.invoke("terminal-resize", agentId, cols, rows);
30
+ },
31
+ terminalKill: (agentId) => {
32
+ return import_electron.ipcRenderer.invoke("terminal-kill", agentId);
33
+ },
34
+ terminalExists: (agentId) => {
35
+ return import_electron.ipcRenderer.invoke("terminal-exists", agentId);
36
+ },
37
+ terminalAttach: (agentId) => {
38
+ return import_electron.ipcRenderer.invoke("terminal-attach", agentId);
39
+ },
40
+ terminalDetach: (agentId) => {
41
+ return import_electron.ipcRenderer.invoke("terminal-detach", agentId);
42
+ },
43
+ terminalPopOut: (agentId) => {
44
+ return import_electron.ipcRenderer.invoke("terminal-pop-out", agentId);
45
+ },
46
+ // Session persistence
47
+ saveSessionId: (agentId, sessionId) => {
48
+ return import_electron.ipcRenderer.invoke("save-session-id", agentId, sessionId);
49
+ },
50
+ getSessionId: (agentId) => {
51
+ return import_electron.ipcRenderer.invoke("get-session-id", agentId);
52
+ },
53
+ // Terminal event listeners
54
+ onTerminalData: (callback) => {
55
+ import_electron.ipcRenderer.on("terminal-data", (_event, agentId, data) => callback(agentId, data));
56
+ },
57
+ onTerminalExit: (callback) => {
58
+ import_electron.ipcRenderer.on("terminal-exit", (_event, agentId, exitCode) => callback(agentId, exitCode));
59
+ },
60
+ onTerminalPreloadStatus: (callback) => {
61
+ import_electron.ipcRenderer.on("terminal-preload-status", (_event, agentId, status) => callback(agentId, status));
62
+ },
63
+ // Copilot activity event listeners
64
+ onCopilotEvent: (callback) => {
65
+ import_electron.ipcRenderer.on("copilot-event", (_event, agentId, copilotEvent) => callback(agentId, copilotEvent));
66
+ },
67
+ onCopilotToolStart: (callback) => {
68
+ import_electron.ipcRenderer.on("copilot-tool-start", (_event, agentId, toolName, toolId, status) => callback(agentId, toolName, toolId, status));
69
+ },
70
+ onCopilotToolComplete: (callback) => {
71
+ import_electron.ipcRenderer.on("copilot-tool-complete", (_event, agentId, toolId, success) => callback(agentId, toolId, success));
72
+ },
73
+ onCopilotTurnEnd: (callback) => {
74
+ import_electron.ipcRenderer.on("copilot-turn-end", (_event, agentId) => callback(agentId));
75
+ },
76
+ onCopilotUserMessage: (callback) => {
77
+ import_electron.ipcRenderer.on("copilot-user-message", (_event, agentId) => callback(agentId));
78
+ },
79
+ removeTerminalListeners: () => {
80
+ import_electron.ipcRenderer.removeAllListeners("terminal-data");
81
+ import_electron.ipcRenderer.removeAllListeners("terminal-exit");
82
+ },
83
+ removeCopilotListeners: () => {
84
+ import_electron.ipcRenderer.removeAllListeners("copilot-event");
85
+ import_electron.ipcRenderer.removeAllListeners("copilot-tool-start");
86
+ import_electron.ipcRenderer.removeAllListeners("copilot-tool-complete");
87
+ import_electron.ipcRenderer.removeAllListeners("copilot-turn-end");
88
+ import_electron.ipcRenderer.removeAllListeners("copilot-user-message");
89
+ }
90
+ });