mirror of
https://github.com/microsoft/vscode.git
synced 2026-06-29 10:56:24 +01:00
a97573159d
* Agent Host changes for agents/adhoc-request-sender-mode-extension-55e2bb6f * Remove unconfigured react-hooks/exhaustive-deps eslint directive The eslint-disable directive referenced a rule that isn't registered in this repo's ESLint config, which caused ESLint to error with "Definition for rule 'react-hooks/exhaustive-deps' was not found" and failed the Compile & Hygiene and Copilot - Test CI checks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Coalesce adhoc tag-decoration rescans with requestAnimationFrame Rescanning the whole editor text on every content change is wasteful for bursty updates (e.g. a streamed response). Debounce the decoration update to at most once per animation frame and cancel any pending frame during cleanup so the callback can't run after the editor is disposed. The initial scan stays synchronous so tags are highlighted immediately on mount. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR feedback: dispose token source; validate adhoc request JSON - adhocRequestSender: always dispose the per-send CancellationTokenSource in the finally block (separate from the current-send guard) so its cancellation listeners don't leak across repeated Send/Stop cycles. - simulationMain: validate and normalize the adhoc request JSON before use so malformed input (missing/null/wrong-typed model/user/system) yields a focused error message instead of a thrown stack trace. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
143 lines
4.2 KiB
JavaScript
143 lines
4.2 KiB
JavaScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
//@ts-check
|
|
|
|
const electron = require('electron');
|
|
const child_process = require('child_process');
|
|
const path = require('path');
|
|
|
|
const app = electron.app;
|
|
|
|
/**
|
|
* @type {Electron.BrowserWindow | null}
|
|
* The main window of the Electron application.
|
|
*/
|
|
let mainWindow = null;
|
|
|
|
function createWindow() {
|
|
const { width, height } = electron.screen.getPrimaryDisplay().workAreaSize;
|
|
mainWindow = new electron.BrowserWindow({
|
|
width: width * 0.75,
|
|
height: height,
|
|
webPreferences: {
|
|
nodeIntegration: true,
|
|
contextIsolation: false
|
|
}
|
|
});
|
|
mainWindow.loadURL(`file://${__dirname}/simulationWorkbench.html`);
|
|
mainWindow.on('closed', function () {
|
|
mainWindow = null;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Installs a standard application menu. This is required for the clipboard
|
|
* keyboard shortcuts (Cmd/Ctrl+C/V/X) to be delivered to the web contents -
|
|
* without an Edit menu containing the paste role, pasting into editors (e.g.
|
|
* the Monaco editors in the "Adhoc request sender" mode) does not work,
|
|
* especially on macOS.
|
|
*/
|
|
function setupApplicationMenu() {
|
|
/** @type {Electron.MenuItemConstructorOptions[]} */
|
|
const template = [];
|
|
if (process.platform === 'darwin') {
|
|
template.push({ role: 'appMenu' });
|
|
}
|
|
template.push({ role: 'fileMenu' });
|
|
template.push({ role: 'editMenu' });
|
|
template.push({ role: 'viewMenu' });
|
|
template.push({ role: 'windowMenu' });
|
|
|
|
electron.Menu.setApplicationMenu(electron.Menu.buildFromTemplate(template));
|
|
}
|
|
|
|
app.on('ready', () => {
|
|
if (process.argv.includes('--help')) {
|
|
console.log(`Options:
|
|
--run-dir=DIRNAME Provide the run output directory name, e.g., 'out-20231201-151346'.
|
|
--grep=STRING Pre-populates simulation workbench 'grep' input box.`);
|
|
app.quit();
|
|
}
|
|
setupApplicationMenu();
|
|
registerListeners();
|
|
createWindow();
|
|
});
|
|
|
|
app.on('window-all-closed', function () {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
app.on('activate', function () {
|
|
if (mainWindow === null) {
|
|
createWindow();
|
|
}
|
|
});
|
|
|
|
// change to configure logging, e.g., to `console.debug`
|
|
const log = {
|
|
debug: (..._args) => { }
|
|
};
|
|
|
|
function registerListeners() {
|
|
|
|
/** @type {Map<string, child_process.ChildProcess>} */
|
|
const spawnedProcesses = new Map();
|
|
|
|
/**
|
|
* Spawns a new child process and sets up listeners for its stdout, stderr, and exit events.
|
|
*
|
|
* @param {Object} event - The event object from the Electron IPC.
|
|
* @param {Object} options - The options for the child process.
|
|
* @param {string} options.id - The unique identifier for the child process created by the renderer process.
|
|
* @param {Array<string>} options.processArgs - The arguments to pass to the child process.
|
|
*/
|
|
function spawnProcess(event, { id, processArgs }) {
|
|
|
|
log.debug(`main process: spawn-process (id: ${id}, processArgs: ${JSON.stringify(processArgs)})`);
|
|
|
|
const child = child_process.spawn(
|
|
'node',
|
|
[path.join(__dirname, '../../dist', 'simulationMain.js'), ...processArgs],
|
|
{ stdio: 'pipe' }
|
|
);
|
|
if (child.pid) {
|
|
child.stdout.setEncoding('utf8');
|
|
child.stdout.on('data', (data) => {
|
|
log.debug(`main process: stdout: ${data.toString()}`);
|
|
event.sender.send('stdout-data', { id, data });
|
|
});
|
|
child.stderr.setEncoding('utf8');
|
|
child.stderr.on('data', (data) => {
|
|
log.debug(`main process: stderr: ${data.toString()}`);
|
|
event.sender.send('stderr-data', { id, data });
|
|
});
|
|
child.on('exit', (code) => {
|
|
log.debug('main process: ' + JSON.stringify(code, null, '\t'));
|
|
spawnedProcesses.delete(id);
|
|
event.sender.send('process-exit', { id, code });
|
|
});
|
|
spawnedProcesses.set(id, child);
|
|
}
|
|
}
|
|
|
|
electron.ipcMain.on('spawn-process', spawnProcess);
|
|
|
|
electron.ipcMain.on('kill-process', (_event, { id }) => {
|
|
spawnedProcesses.get(id)?.kill('SIGTERM');
|
|
spawnedProcesses.delete(id);
|
|
});
|
|
|
|
electron.ipcMain.on('open-link', (_event, url) => {
|
|
electron.shell.openExternal(url);
|
|
});
|
|
|
|
electron.ipcMain.handle('processArgv', () => {
|
|
return process.argv;
|
|
});
|
|
}
|