diff --git a/package-lock.json b/package-lock.json index 749e4e3..9b07464 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "witsy", - "version": "1.6.0", + "version": "1.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "witsy", - "version": "1.6.0", + "version": "1.7.1", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.20.4", "@el3um4s/run-vbs": "^1.1.2", + "@excalidraw/markdown-to-text": "^0.1.2", "@google/generative-ai": "^0.11.1", "@iktakahiro/markdown-it-katex": "^4.0.1", "@mistralai/mistralai": "^0.1.3", @@ -27,7 +28,6 @@ "katex": "^0.16.10", "markdown-it": "^14.1.0", "markdown-it-mark": "^4.0.0", - "markdown-to-text": "^0.1.1", "minimatch": "^9.0.4", "mitt": "^3.0.1", "officeparser": "^4.1.1", @@ -2014,6 +2014,11 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@excalidraw/markdown-to-text": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@excalidraw/markdown-to-text/-/markdown-to-text-0.1.2.tgz", + "integrity": "sha512-1nDXBNAojfi3oSFwJswKREkFm5wrSjqay81QlyRv2pkITG/XYB5v+oChENVBQLcxQwX4IUATWvXM5BcaNhPiIg==" + }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -3307,11 +3312,6 @@ "@types/responselike": "^1.0.0" } }, - "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==" - }, "node_modules/@types/concat-stream": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", @@ -3464,11 +3464,6 @@ "dev": true, "optional": true }, - "node_modules/@types/mocha": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", - "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==" - }, "node_modules/@types/node": { "version": "20.12.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", @@ -12922,15 +12917,6 @@ "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-4.0.0.tgz", "integrity": "sha512-YLhzaOsU9THO/cal0lUjfMjrqSMPjjyjChYM7oyj4DnyaXEzA8gnW6cVJeyCrCVeyesrY2PlEdUYJSPFYL4Nkg==" }, - "node_modules/markdown-to-text": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/markdown-to-text/-/markdown-to-text-0.1.1.tgz", - "integrity": "sha512-co/J5l8mJ2RK9wD/nQRGwO7JxoeyfvVNtOZll016EdAX2qYkwCWMdtYvJO42b41Ho7GFEJMuly9llf0Nj+ReQw==", - "dependencies": { - "@types/chai": "^4.2.14", - "@types/mocha": "^8.2.0" - } - }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", diff --git a/package.json b/package.json index f26d17c..7a39f8d 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "dependencies": { "@anthropic-ai/sdk": "^0.20.4", "@el3um4s/run-vbs": "^1.1.2", + "@excalidraw/markdown-to-text": "^0.1.2", "@google/generative-ai": "^0.11.1", "@iktakahiro/markdown-it-katex": "^4.0.1", "@mistralai/mistralai": "^0.1.3", @@ -81,7 +82,6 @@ "katex": "^0.16.10", "markdown-it": "^14.1.0", "markdown-it-mark": "^4.0.0", - "markdown-to-text": "^0.1.1", "minimatch": "^9.0.4", "mitt": "^3.0.1", "officeparser": "^4.1.1", diff --git a/src/automations/anywhere.ts b/src/automations/anywhere.ts index 5c46c26..1a2974f 100644 --- a/src/automations/anywhere.ts +++ b/src/automations/anywhere.ts @@ -4,7 +4,7 @@ import { App } from 'electron' import { loadSettings } from '../main/config' import { igniteEngine } from '../services/llm' import { LlmResponse } from '../types/llm.d' -import removeMarkdown from 'markdown-to-text' +import { removeMarkdown } from '@excalidraw/markdown-to-text' import LlmEngine from '../services/engine' import Automator from './automator' import Message from '../models/message' @@ -20,7 +20,7 @@ export default class PromptAnywhere { this.cancelled = false } - cancel = async () => { + cancel = async (): Promise => { // close stuff await window.closeWaitingPanel(); @@ -32,6 +32,11 @@ export default class PromptAnywhere { } + static initPrompt = async (): Promise => { + await window.hideWindows(); + await window.openPromptAnywhere(); + } + execPrompt = async (app: App, prompt: string): Promise => { try { @@ -68,7 +73,6 @@ export default class PromptAnywhere { // done await window.closeWaitingPanel(); - await window.restoreWindows(); await window.releaseFocus(); // now paste @@ -78,13 +82,17 @@ export default class PromptAnywhere { const automator = new Automator(); await automator.pasteText(result) + // done + await window.restoreWindows(); + await window.releaseFocus(); + return; } catch (error) { console.error('Error while testing', error); } // done waiting - await window.closeWaitingPanel(true); + await window.closeWaitingPanel(); await window.restoreWindows(); await window.releaseFocus(); diff --git a/src/automations/commander.ts b/src/automations/commander.ts index c32bd05..943a5d7 100644 --- a/src/automations/commander.ts +++ b/src/automations/commander.ts @@ -6,7 +6,7 @@ import { LlmResponse } from '../types/llm.d' import { App, BrowserWindow, Notification } from 'electron' import { loadSettings } from '../main/config' import { igniteEngine } from '../services/llm' -import removeMarkdown from 'markdown-to-text' +import { removeMarkdown } from '@excalidraw/markdown-to-text' import Message from '../models/message' import Automator from './automator' import LlmEngine from '../services/engine' @@ -158,7 +158,6 @@ export default class Commander { // done await window.closeWaitingPanel(); - await window.restoreWindows(); await window.releaseFocus(); // now paste @@ -166,6 +165,8 @@ export default class Commander { await this.finishCommand(command, result.response, engine, model); // done + await window.restoreWindows(); + await window.releaseFocus(); return result; } @@ -175,7 +176,7 @@ export default class Commander { } // done waiting - await window.closeWaitingPanel(true); + await window.closeWaitingPanel(); await window.restoreWindows(); await window.releaseFocus(); diff --git a/src/main.ts b/src/main.ts index 3522c71..2896589 100644 --- a/src/main.ts +++ b/src/main.ts @@ -59,7 +59,7 @@ const registerShortcuts = () => { shortcuts.registerShortcuts(app, { chat: window.openMainWindow, command: Commander.initCommand, - anywhere: window.openPromptAnywhere, + anywhere: PromptAnywhere.initPrompt, }); } @@ -79,7 +79,7 @@ const buildTrayMenu = () => { return [ { label: 'New Chat', accelerator: shortcuts.shortcutAccelerator(configShortcuts?.chat), click: window.openMainWindow }, - { label: 'Prompt Anywhere', accelerator: shortcuts.shortcutAccelerator(configShortcuts?.anywhere), click: window.openPromptAnywhere }, + { label: 'Prompt Anywhere', accelerator: shortcuts.shortcutAccelerator(configShortcuts?.anywhere), click: PromptAnywhere.initPrompt }, { label: 'Run AI Command', accelerator: shortcuts.shortcutAccelerator(configShortcuts?.command), click: Commander.initCommand }, { type: 'separator'}, { label: 'Settingsā€¦', click: window.openSettingsWindow }, @@ -365,6 +365,9 @@ ipcMain.on('run-python-code', async (event, payload) => { ipcMain.on('prompt-anywhere', async (event, payload) => { + // if cancel on prompt window + await window.closePromptAnywhere(); + // cancel previous if (anywhere != null) { await anywhere.cancel(); @@ -384,7 +387,6 @@ ipcMain.on('cancel-anywhere', async () => { // if cancel on prompt window await window.closePromptAnywhere(); - await window.releaseFocus(); // if cancel on waiting panel if (anywhere != null) { diff --git a/src/main/window.ts b/src/main/window.ts index 194e423..8000fe3 100644 --- a/src/main/window.ts +++ b/src/main/window.ts @@ -186,7 +186,7 @@ export const hideWindows = async () => { // remember to restore all windows windowsToRestore = []; try { - console.log('Hiding windows'); + // console.log('Hiding windows'); const windows = BrowserWindow.getAllWindows(); for (const window of windows) { if (!window.isDestroyed() && window.isVisible() && !window.isMinimized()) { @@ -194,7 +194,6 @@ export const hideWindows = async () => { window.hide(); } } - await releaseFocus(); } catch (error) { console.error('Error while hiding active windows', error); } @@ -204,7 +203,7 @@ export const hideWindows = async () => { export const restoreWindows = () => { // log - console.log(`Restoring ${windowsToRestore.length} windows`) + // console.log(`Restoring ${windowsToRestore.length} windows`) // restore main window first windowsToRestore.sort((a, b) => { @@ -232,9 +231,11 @@ let commandPalette: BrowserWindow = null; export const closeCommandPalette = async () => { try { if (commandPalette && !commandPalette.isDestroyed()) { + // console.log('Closing command palette') commandPalette?.close() await wait(); } + commandPalette = null; } catch (error) { console.error('Error while closing command palette', error); } @@ -274,11 +275,11 @@ export const openCommandPalette = async (textId: string) => { } let waitingPanel: BrowserWindow = null; -export const closeWaitingPanel = async (destroy?: boolean) => { +export const closeWaitingPanel = async () => { try { if (waitingPanel && !waitingPanel.isDestroyed()) { - if (destroy) waitingPanel?.destroy() - else waitingPanel?.close() + // console.log('Closing waiting panel') + waitingPanel?.close() await wait(); } waitingPanel = null; @@ -289,7 +290,8 @@ export const closeWaitingPanel = async (destroy?: boolean) => { export const openWaitingPanel = () => { - // try to show existig one + // try to close existig one + // console.log('Opening waiting panel') closeWaitingPanel(); // get bounds @@ -297,15 +299,17 @@ export const openWaitingPanel = () => { const height = 20; const { x, y } = screen.getCursorScreenPoint(); - // else open a new one + // open a new one waitingPanel = createWindow({ hash: '/wait', x: x - width/2, - y: y - height*2, + y: y - height*1.5, width: width, height: height, frame: false, + skipTaskbar: true, alwaysOnTop: true, + hiddenInMissionControl: true, hasShadow: false, }); @@ -333,37 +337,38 @@ export const openSettingsWindow = () => { let promptAnywhereWindow: BrowserWindow = null; export const openPromptAnywhere = () => { - // try to show existig one - closePromptAnywhere(); + // try to close existig one + closePromptAnywhere(); - // get bounds - const width = 500; - const height = 48; - const { x, y } = screen.getCursorScreenPoint(); - - // open a new one - promptAnywhereWindow = createWindow({ - hash: '/prompt', - x: x - width/2, - y: y - 24, - width: width, - height: height, - frame: false, - skipTaskbar: true, - alwaysOnTop: true, - hiddenInMissionControl: true, - }); - - promptAnywhereWindow.on('blur', () => { - closePromptAnywhere(); - restoreWindows(); - }); + // get bounds + const width = 500; + const height = 48; + const { x, y } = screen.getCursorScreenPoint(); + + // open a new one + promptAnywhereWindow = createWindow({ + hash: '/prompt', + x: x - width/2, + y: y - 24, + width: width, + height: height, + frame: false, + skipTaskbar: true, + alwaysOnTop: true, + hiddenInMissionControl: true, + }); + + promptAnywhereWindow.on('blur', () => { + closePromptAnywhere(); + restoreWindows(); + }); }; export const closePromptAnywhere = async () => { try { if (promptAnywhereWindow && !promptAnywhereWindow.isDestroyed()) { + // console.log('Closing prompt anywhere window') promptAnywhereWindow?.close() await wait(); }