diff --git a/LICENSE b/LICENSE index 5bda875..c5f0ea2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 2017 - 2021 Joseph Kato and Chris Ward +Copyright (c) 2017 - 2022 Joseph Kato and Chris Ward Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index d104a68..7c723fb 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,16 @@ # Vale + VS Code -> The official Visual Studio Code extension for [Vale](https://github.com/errata-ai/vale) and [Vale Server](https://errata.ai/vale-server/). +> The official Visual Studio Code extension for [Vale](https://github.com/errata-ai/vale). The Vale extension for VS Code provides customizable spelling, style, and grammar checking for a variety of markup formats (Markdown, AsciiDoc, reStructuredText, HTML, and DITA). -As of **v0.10.0**, the extension supports both [Vale](https://github.com/errata-ai/vale) (the command-line tool) and [Vale Server](https://errata.ai/vale-server/) (the desktop application). +As of **v0.15.0**, the extension drops support for [Vale Server](https://errata.ai/vale-server/) which has ceased development. Many of the features from Vale Server will find their way into the Vale CLI tool, and this extension. ## Installation -> **NOTE**: While this extension supports both Vale CLI and Vale Server, many of the extension's more [advanced features](#features) (such as Quick Fixes and Vocabulary Management) are only available through Vale Server. - -### Using Vale Server - -1. Install [Vale Server](https://errata.ai/vale-server/); - -2. install `vale-vscode` (this extension) via the [Marketplace](https://marketplace.visualstudio.com/items?itemName=errata-ai.vale-server); and - -3. restart VS Code (recommended). - -### Using Vale - 1. Install [Vale](https://docs.errata.ai/vale/install); - 2. install `vale-vscode` (this extension) via the [Marketplace](https://marketplace.visualstudio.com/items?itemName=errata-ai.vale-server); - -3. set [`vale.core.useCLI`](#settings) to `true` in the extension settings (_Preferences > Extensions > Vale > Use CLI_); and - -4. restart VS Code (recommended). +3. restart VS Code (recommended). ## Features @@ -74,11 +58,9 @@ Use the `Vale: View Folder Report` command to generate a [report for the active ## Settings -The extension offers a number of settings and configuration options (_Preferences > Extensions > Vale_), which are split into three groups: `Vale > Core` (Vale and Vale Server), `Vale > Server` (Vale Server only), and `Vale > Vale CLI` (Vale only). - -- `vale.core.useCLI` (default: `false`): Use Vale CLI instead of Vale Server. +The extension offers a number of settings and configuration options (_Preferences > Extensions > Vale_).. -- `vale.server.serverURL` (default: `http://127.0.0.1:7777`): URL to your running Vale Server instance. + - `vale.server.provideFixes` (default: `true`): Offer solutions to alerts using the 'Quick Fix' button. diff --git a/package.json b/package.json index 4aa6e50..6bde973 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "vale-server", + "name": "vale", "displayName": "Vale", "icon": ".vscode/icon.png", - "description": "The official Visual Studio Code extension for Vale and Vale Server.", + "description": "The official Visual Studio Code extension for Vale.", "bugs": "https://github.com/errata-ai/vale-vscode/issues", "author": { "name": "Joseph Kato", @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/errata-ai/vale-vscode.git" }, - "version": "0.14.2", + "version": "0.15.0", "engines": { "vscode": "^1.43.0" }, @@ -106,11 +106,6 @@ "default": false, "markdownDescription": "Use Vale's CLI instead of Vale Server. (**NOTE**: Some features, such as [Quick Fixes](https://github.com/errata-ai/vale-vscode/pull/4) and [Vocab Management](https://github.com/errata-ai/vale-vscode/pull/4), are only available when using Vale Server.)" }, - "vale.server.serverURL": { - "type": "string", - "default": "http://127.0.0.1:7777", - "description": "URL to your running Vale Server instance." - }, "vale.server.provideFixes": { "type": "boolean", "default": true, @@ -150,13 +145,6 @@ "Sets `minAlertLevel` to `error`, overriding any configuration files." ], "markdownDescription": "Defines from which level of errors and above to display in the problems output." - }, - "vale-server.serverURL": { - "type": "string", - "default": "http://127.0.0.1:7777", - "description": "URL to your running Vale Server instance.", - "markdownDeprecationMessage": "**Deprecated**: Please use `#vale.server.serverURL#` instead.", - "deprecationMessage": "Deprecated: Please use vale.server.serverURL instead." } } } @@ -172,25 +160,22 @@ "test-compile": "tsc -p ./" }, "devDependencies": { - "@types/glob": "^7.1.1", - "@types/mocha": "^9.0.0", - "@types/node": "^10.12.21", - "@types/vscode": "^1.59.0", - "@types/which": "^1.3", - "glob": "^7.1.4", - "mocha": "^9.1.0", - "ts-loader": "^6.1.2", - "tslint": "^5.12.1", - "typescript": "^4.3.5", + "@types/glob": "^7.2.0", + "@types/mocha": "^9.1.1", + "@types/node": "^18.0.0", + "@types/vscode": "^1.68.1", + "@types/which": "^2.0.1", + "glob": "^8.0.3", + "mocha": "^10.0.0", + "ts-loader": "^9.3.1", + "tslint": "^6.1.3", + "typescript": "^4.7.4", "vscode-test": "^1.6.1", - "webpack": "^5.51.1", - "webpack-cli": "^4.8.0" + "webpack": "^5.73.0", + "webpack-cli": "^4.10.0" }, "dependencies": { - "@types/request-promise-native": "^1.0.16", - "fs": "0.0.1-security", - "request": "^2.88.0", - "request-promise-native": "^1.0.7", - "which": "^2.0.1" + "which": "^2.0.2", + "fs": "0.0.1-security" } } diff --git a/src/extension.ts b/src/extension.ts index f65ac4e..8d1e89c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,8 +1,8 @@ import * as vscode from "vscode"; -import ValeServerProvider from "./features/vsProvider"; +import ValeProvider from "./features/vsProvider"; export function activate(context: vscode.ExtensionContext) { - let linter = new ValeServerProvider(); + let linter = new ValeProvider(); linter.activate(context.subscriptions); } diff --git a/src/features/vsCommands.ts b/src/features/vsCommands.ts index b4a64ff..b896fe8 100644 --- a/src/features/vsCommands.ts +++ b/src/features/vsCommands.ts @@ -1,7 +1,7 @@ import * as vscode from "vscode"; import * as path from "path"; -import * as request from "request-promise-native"; +// import * as request from "request-promise-native"; /** * An Alert From Vale. @@ -13,11 +13,11 @@ interface IValeConfigJSON { export default function InitCommands(subscriptions: vscode.Disposable[]) { subscriptions.push( - vscode.commands.registerCommand("vale.addToAccept", addToAccept), - vscode.commands.registerCommand("vale.addToReject", addToReject), + // vscode.commands.registerCommand("vale.addToAccept", addToAccept), + // vscode.commands.registerCommand("vale.addToReject", addToReject), - vscode.commands.registerCommand("vale.openAccept", openAccept), - vscode.commands.registerCommand("vale.openReject", openReject), + // vscode.commands.registerCommand("vale.openAccept", openAccept), + // vscode.commands.registerCommand("vale.openReject", openReject), vscode.commands.registerCommand("vale.doSummary", doSummary) ); @@ -29,138 +29,138 @@ const doSummary = async () => { return; } - let server: string = vscode.workspace - .getConfiguration() - .get("vale.server.serverURL", "http://localhost:7777"); + // let server: string = vscode.workspace + // .getConfiguration() + // // .get("vale.server.serverURL", "http://localhost:7777"); - let name = path.dirname(editor.document.fileName); - let link = server + `/summary.html?path=${name}`; + // let name = path.dirname(editor.document.fileName); + // // let link = server + `/summary.html?path=${name}`; - vscode.env.openExternal(vscode.Uri.parse(link)); + // vscode.env.openExternal(vscode.Uri.parse(link)); }; -const addToAccept = async () => { - await addToVocab("accept"); -}; -const addToReject = async () => { - await addToVocab("reject"); -}; +// const addToAccept = async () => { +// await addToVocab("accept"); +// }; +// const addToReject = async () => { +// await addToVocab("reject"); +// }; -const openAccept = async () => { - await openVocabFile("accept"); -}; -const openReject = async () => { - await openVocabFile("reject"); -}; +// const openAccept = async () => { +// await openVocabFile("accept"); +// }; +// const openReject = async () => { +// await openVocabFile("reject"); +// }; /** * Get the user's active Vale Server configuration. */ -const getConfig = async (server: string): Promise => { - let config: IValeConfigJSON = {} as IValeConfigJSON; - - await request - .get({ uri: server + "/config", json: true }) - .catch((error) => { - throw new Error(`Vale Server could not connect: ${error}.`); - }) - .then((body) => { - config = body; - }); - - return config; -}; - -const openVocabFile = async (name: string) => { - const configuration = vscode.workspace.getConfiguration(); - const server: string = configuration.get( - "vale.server.serverURL", - "http://localhost:7777" - ); - const config: IValeConfigJSON = await getConfig(server); - - const src = path.join( - config.StylesPath, - "Vocab", - config.Project, - name + ".txt" - ); - vscode.workspace - .openTextDocument(src) - .then((doc) => vscode.window.showTextDocument(doc)); -}; +// const getConfig = async (server: string): Promise => { +// let config: IValeConfigJSON = {} as IValeConfigJSON; + +// await request +// .get({ uri: server + "/config", json: true }) +// .catch((error) => { +// throw new Error(`Vale Server could not connect: ${error}.`); +// }) +// .then((body) => { +// config = body; +// }); + +// return config; +// }; + +// const openVocabFile = async (name: string) => { +// const configuration = vscode.workspace.getConfiguration(); +// const server: string = configuration.get( +// "vale.server.serverURL", +// "http://localhost:7777" +// ); +// const config: IValeConfigJSON = await getConfig(server); + +// const src = path.join( +// config.StylesPath, +// "Vocab", +// config.Project, +// name + ".txt" +// ); +// vscode.workspace +// .openTextDocument(src) +// .then((doc) => vscode.window.showTextDocument(doc)); +// }; /** * Add the currently-selected word to the user's active Vocab. */ -const addToVocab = async (filename: string) => { - const editor = vscode.window.activeTextEditor; - if (!editor) { - return; - } - - const configuration = vscode.workspace.getConfiguration(); - const server: string = configuration.get( - "vale.server.serverURL", - "http://localhost:7777" - ); - const config: IValeConfigJSON = await getConfig(server); - - const word: string = editor.document.getText(editor.selection); - const name: string = config.Project; - const styles: string = config.StylesPath; - - await request - .get({ - uri: server + "/vocab", - qs: { - name: name, - file: filename, - }, - json: true, - }) - .catch((error) => { - throw new Error(`Vale Server could not connect: ${error}.`); - }) - .then((contents: Array) => { - contents.push(word); - - // TODO: Do we need to (shoud we?) sort ourselves? - let body = [...new Set(contents)].sort((a, b) => { - if (a.toLowerCase() > b.toLowerCase()) { - return 1; - } else if (a.toLowerCase() < b.toLowerCase()) { - return -1; - } - return 0; - }); - - request - .post({ - uri: server + "/update", - qs: { - path: name + "." + filename, - text: body.join("\n"), - }, - json: true, - }) - .catch((error) => { - throw new Error(`Vale Server could not connect: ${error}.`); - }) - .then(() => { - const src = path.join(styles, "Vocab", name, filename + ".txt"); - vscode.window - .showInformationMessage( - `Successfully added '${word}' to '${name}' vocab.`, - ...["View File"] - ) - .then((selection) => { - if (selection === "View File") { - vscode.workspace - .openTextDocument(src) - .then((doc) => vscode.window.showTextDocument(doc)); - } - }); - }); - }); -}; +// const addToVocab = async (filename: string) => { +// const editor = vscode.window.activeTextEditor; +// if (!editor) { +// return; +// } + +// const configuration = vscode.workspace.getConfiguration(); +// const server: string = configuration.get( +// "vale.server.serverURL", +// "http://localhost:7777" +// ); +// const config: IValeConfigJSON = await getConfig(server); + +// const word: string = editor.document.getText(editor.selection); +// const name: string = config.Project; +// const styles: string = config.StylesPath; + +// await request +// .get({ +// uri: server + "/vocab", +// qs: { +// name: name, +// file: filename, +// }, +// json: true, +// }) +// .catch((error) => { +// throw new Error(`Vale Server could not connect: ${error}.`); +// }) +// .then((contents: Array) => { +// contents.push(word); + +// // TODO: Do we need to (shoud we?) sort ourselves? +// let body = [...new Set(contents)].sort((a, b) => { +// if (a.toLowerCase() > b.toLowerCase()) { +// return 1; +// } else if (a.toLowerCase() < b.toLowerCase()) { +// return -1; +// } +// return 0; +// }); + +// request +// .post({ +// uri: server + "/update", +// qs: { +// path: name + "." + filename, +// text: body.join("\n"), +// }, +// json: true, +// }) +// .catch((error) => { +// throw new Error(`Vale Server could not connect: ${error}.`); +// }) +// .then(() => { +// const src = path.join(styles, "Vocab", name, filename + ".txt"); +// vscode.window +// .showInformationMessage( +// `Successfully added '${word}' to '${name}' vocab.`, +// ...["View File"] +// ) +// .then((selection) => { +// if (selection === "View File") { +// vscode.workspace +// .openTextDocument(src) +// .then((doc) => vscode.window.showTextDocument(doc)); +// } +// }); +// }); +// }); +// }; diff --git a/src/features/vsProvider.ts b/src/features/vsProvider.ts index e1d3f7a..ae99e96 100644 --- a/src/features/vsProvider.ts +++ b/src/features/vsProvider.ts @@ -2,13 +2,12 @@ import * as path from "path"; import * as fs from "fs"; -import * as request from "request-promise-native"; import * as vscode from "vscode"; -import InitCommands from "./vsCommands"; +// import InitCommands from "./vsCommands"; import * as utils from "./vsUtils"; -export default class ValeServerProvider implements vscode.CodeActionProvider { +export default class ValeProvider implements vscode.CodeActionProvider { private diagnosticCollection!: vscode.DiagnosticCollection; private readabilityStatus!: vscode.StatusBarItem; private alertMap: Record = {}; @@ -16,7 +15,7 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { private stylesPath!: string; private useCLI!: boolean; - private static commandId: string = "ValeServerProvider.runCodeAction"; + private static commandId: string = "ValeProvider.runCodeAction"; private command!: vscode.Disposable; private logger!: vscode.OutputChannel; @@ -29,33 +28,13 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { // Reset out alert map and run-time log: this.alertMap = {}; this.logger.clear(); - - this.useCLI = configuration.get("vale.core.useCLI", false); - - if (!this.useCLI) { - // We're using Vale Server ... - const limit = configuration.get("vale.server.lintContext", 0); - - let response: string = ""; - if (limit < 0 || (limit > 0 && textDocument.lineCount >= limit)) { - const ext = path.extname(textDocument.fileName); - const ctx = utils.findContext(); - - response = await utils.postString(ctx.Content, ext); - this.handleJSON(response, textDocument, ctx.Offset); - } else { - response = await utils.postFile(textDocument); - this.handleJSON(response, textDocument, 0); - } - } else { - // We're using the CLI ... - try { - await this.runVale(textDocument); - } catch (error) { - vscode.window.showErrorMessage( - `There was an error running Vale ${error}.` - ); - } + // We're using the CLI ... + try { + await this.runVale(textDocument); + } catch (error) { + vscode.window.showErrorMessage( + `There was an error running Vale ${error}.` + ); } } @@ -108,7 +87,7 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { const stdout = await utils.runInWorkspace(folder, command); this.handleJSON(stdout.toString(), file, 0); } catch (error) { - this.logger.appendLine(error); + this.logger.appendLine(error as string); } } @@ -118,7 +97,7 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { offset: number ) { const diagnostics: vscode.Diagnostic[] = []; - const backend = this.useCLI ? "Vale" : "Vale Server"; + const backend = "Vale"; let body = JSON.parse(contents.toString()); if (body.Code && body.Text) { this.logger.appendLine(body.Text); @@ -160,6 +139,7 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { this.readabilityStatus.show(); } + // TODO: Will any of this work? public async provideCodeActions( document: vscode.TextDocument, range: vscode.Range, @@ -169,52 +149,75 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { let diagnostic: vscode.Diagnostic = context.diagnostics[0]; let actions: vscode.CodeAction[] = []; - if (diagnostic === undefined || this.useCLI) { - return actions; - } - + // if (diagnostic === undefined || this.useCLI) { + // return actions; + // } let key = `${diagnostic.message}-${diagnostic.range}`; let alert = this.alertMap[key]; - - let server: string = vscode.workspace - .getConfiguration() - .get("vale.server.serverURL", "http://localhost:7777"); - - await request - .post({ - uri: server + "/suggest", - qs: { alert: JSON.stringify(alert) }, - json: true, - }) - .catch((error) => { - return Promise.reject(`Vale Server could not connect: ${error}.`); - }) - .then((body) => { - for (let idx in body["suggestions"]) { - const suggestion = body["suggestions"][idx]; - const title = utils.toTitle(alert, suggestion); - const action = new vscode.CodeAction( - title, - vscode.CodeActionKind.QuickFix - ); - - action.command = { - title: title, - command: ValeServerProvider.commandId, - arguments: [ - document, - diagnostic, - alert.Match, - suggestion, - alert.Action.Name, - ], - }; - - actions.push(action); - } - }); - + console.log("A - "); + console.log(alert); + + const suggestion = alert.Action.Params[1]; + console.log("sug"); + console.log(suggestion); + const title = utils.toTitle(alert, suggestion as unknown as string); + const action = new vscode.CodeAction(title, vscode.CodeActionKind.QuickFix); + + action.command = { + title: title, + command: ValeProvider.commandId, + arguments: [ + document, + diagnostic, + alert.Match, + suggestion, + alert.Action.Name, + ], + }; + console.log("ACT - "); + console.log(action); + actions.push(action); return actions; + + // let server: string = vscode.workspace + // .getConfiguration() + // .get("vale.server.serverURL", "http://localhost:7777"); + + // await request + // .post({ + // uri: server + "/suggest", + // qs: { alert: JSON.stringify(alert) }, + // json: true, + // }) + // .catch((error) => { + // return Promise.reject(`Vale Server could not connect: ${error}.`); + // }) + // .then((body) => { + // for (let idx in body["suggestions"]) { + // const suggestion = body["suggestions"][idx]; + // const title = utils.toTitle(alert, suggestion); + // const action = new vscode.CodeAction( + // title, + // vscode.CodeActionKind.QuickFix + // ); + + // action.command = { + // title: title, + // command: ValeProvider.commandId, + // arguments: [ + // document, + // diagnostic, + // alert.Match, + // suggestion, + // alert.Action.Name, + // ], + // }; + + // actions.push(action); + // } + // }); + + // return actions; } private runCodeAction( @@ -228,9 +231,8 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { if (error === docError) { // Remove diagnostic from list - let diagnostics: vscode.Diagnostic[] = this.diagnosticMap[ - document.uri.toString() - ]; + let diagnostics: vscode.Diagnostic[] = + this.diagnosticMap[document.uri.toString()]; let index: number = diagnostics.indexOf(diagnostic); diagnostics.splice(index, 1); @@ -269,7 +271,7 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { const configuration = vscode.workspace.getConfiguration(); this.command = vscode.commands.registerCommand( - ValeServerProvider.commandId, + ValeProvider.commandId, this.runCodeAction, this ); @@ -281,10 +283,10 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { ); this.diagnosticCollection = vscode.languages.createDiagnosticCollection(); - this.useCLI = configuration.get("vale.core.useCLI", false); - if (!this.useCLI) { - this.stylesPath = await utils.getStylesPath(); - } + // this.useCLI = configuration.get("vale.core.useCLI", false); + // if (!this.useCLI) { + // this.stylesPath = await utils.getStylesPath(); + // } vscode.workspace.onDidOpenTextDocument(this.doVale, this, subscriptions); vscode.workspace.onDidCloseTextDocument( @@ -303,7 +305,7 @@ export default class ValeServerProvider implements vscode.CodeActionProvider { this ); - InitCommands(subscriptions); + // InitCommands(subscriptions); } public dispose(): void { diff --git a/src/features/vsTypes.ts b/src/features/vsTypes.ts index dbf30d3..d442d75 100644 --- a/src/features/vsTypes.ts +++ b/src/features/vsTypes.ts @@ -13,7 +13,7 @@ interface IEditorContext { */ interface IValeActionJSON { readonly Name: string; - readonly Params: [string]; + readonly Params: [number,string]; } /** @@ -30,3 +30,17 @@ interface IValeErrorJSON { readonly Span: [number, number]; readonly Severity: ValeSeverity; } + +// type Fixer +// const fixers: Map = new Map([ +// ['name', 'Tom'], +// ['country', 'Chile'], +// ]); + +// var fixers = map[string]fixer{ +// "suggest": suggest, +// "replace": replace, +// "remove": remove, +// "convert": convert, +// "edit": edit, +// } diff --git a/src/features/vsUtils.ts b/src/features/vsUtils.ts index c139ad1..1d1776f 100644 --- a/src/features/vsUtils.ts +++ b/src/features/vsUtils.ts @@ -1,7 +1,6 @@ import * as path from "path"; import * as which from "which"; import * as fs from "fs"; -import * as request from "request-promise-native"; import { execFile } from "child_process"; import * as vscode from "vscode"; @@ -69,6 +68,8 @@ export const toTitle = (alert: IValeErrorJSON, suggestion: string): string => { switch (alert.Action.Name) { case "remove": return "Remove '" + alert.Match + "'"; + case "replace": + return "Replace with '" + suggestion + "'"; } return "Replace with '" + suggestion + "'"; }; @@ -208,83 +209,26 @@ export const findContext = (): IEditorContext => { return context; }; -export const postFile = async (doc: vscode.TextDocument): Promise => { - let server: string = vscode.workspace - .getConfiguration() - .get("vale.server.serverURL", "http://localhost:7777"); - let response: string = ""; - - await request - .post({ - uri: server + "/file", - qs: { - file: doc.fileName, - path: path.dirname(doc.fileName), - }, - json: true, - }) - .catch((error) => { - vscode.window.showErrorMessage( - `Vale Server could not connect: ${error}.` - ); - }) - .then((body) => { - response = fs.readFileSync(body.path).toString(); - }); - - return response; -}; - -export const postString = async ( - content: string, - ext: string -): Promise => { - let server: string = vscode.workspace - .getConfiguration() - .get("vale.server.serverURL", "http://localhost:7777"); - let response: string = ""; - - await request - .post({ - uri: server + "/vale", - qs: { - text: content, - format: ext, - }, - json: false, - }) - .catch((error) => { - vscode.window.showErrorMessage( - `Vale Server could not connect: ${error}.` - ); - }) - .then((body) => { - response = body; - }); - - return response; -}; - -export const getStylesPath = async (): Promise => { - const configuration = vscode.workspace.getConfiguration(); - - let path: string = ""; - let server: string = configuration.get( - "vale.server.serverURL", - "http://localhost:7777" - ); - - await request - .get({ uri: server + "/path", json: true }) - .catch((error) => { - throw new Error(`Vale Server could not connect: ${error}.`); - }) - .then((body) => { - path = body.path; - }); - - return path; -}; +// export const getStylesPath = async (): Promise => { +// const configuration = vscode.workspace.getConfiguration(); + +// let path: string = ""; +// let server: string = configuration.get( +// "vale.server.serverURL", +// "http://localhost:7777" +// ); + +// await request +// .get({ uri: server + "/path", json: true }) +// .catch((error) => { +// throw new Error(`Vale Server could not connect: ${error}.`); +// }) +// .then((body) => { +// path = body.path; +// }); + +// return path; +// }; export const buildCommand = ( exe: string,