diff --git a/packages/engine.vscode/.eslintrc.js b/packages/engine.vscode/.eslintrc.js
new file mode 100644
index 00000000..f96bb0f1
--- /dev/null
+++ b/packages/engine.vscode/.eslintrc.js
@@ -0,0 +1,23 @@
+/**@type {import('eslint').Linter.Config} */
+// eslint-disable-next-line no-undef
+module.exports = {
+ root: true,
+ parser: '@typescript-eslint/parser',
+ plugins: [
+ '@typescript-eslint',
+ ],
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ ],
+ ignorePatterns: [
+ 'media'
+ ],
+ rules: {
+ 'semi': [2, "always"],
+ '@typescript-eslint/no-unused-vars': 0,
+ '@typescript-eslint/no-explicit-any': 0,
+ '@typescript-eslint/explicit-module-boundary-types': 0,
+ '@typescript-eslint/no-non-null-assertion': 0,
+ }
+};
\ No newline at end of file
diff --git a/packages/engine.vscode/.vscode/extensions.json b/packages/engine.vscode/.vscode/extensions.json
new file mode 100644
index 00000000..af515502
--- /dev/null
+++ b/packages/engine.vscode/.vscode/extensions.json
@@ -0,0 +1,9 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
+ // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
+
+ // List of extensions which should be recommended for users of this workspace.
+ "recommendations": [
+ "dbaeumer.vscode-eslint"
+ ]
+}
\ No newline at end of file
diff --git a/packages/engine.vscode/.vscode/launch.json b/packages/engine.vscode/.vscode/launch.json
new file mode 100644
index 00000000..461f3da0
--- /dev/null
+++ b/packages/engine.vscode/.vscode/launch.json
@@ -0,0 +1,18 @@
+// A launch configuration that compiles the extension and then opens it inside a new window
+// Use IntelliSense to learn about possible attributes.
+// Hover to view descriptions of existing attributes.
+// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Run Extension",
+ "type": "extensionHost",
+ "request": "launch",
+ "runtimeExecutable": "${execPath}",
+ "args": ["--extensionDevelopmentPath=${workspaceRoot}"],
+ "outFiles": ["${workspaceFolder}/out/**/*.js"],
+ "preLaunchTask": "npm: watch"
+ }
+ ]
+}
diff --git a/packages/engine.vscode/.vscode/settings.json b/packages/engine.vscode/.vscode/settings.json
new file mode 100644
index 00000000..8d047dad
--- /dev/null
+++ b/packages/engine.vscode/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "editor.insertSpaces": false
+}
\ No newline at end of file
diff --git a/packages/engine.vscode/.vscode/tasks.json b/packages/engine.vscode/.vscode/tasks.json
new file mode 100644
index 00000000..3b17e53b
--- /dev/null
+++ b/packages/engine.vscode/.vscode/tasks.json
@@ -0,0 +1,20 @@
+// See https://go.microsoft.com/fwlink/?LinkId=733558
+// for the documentation about the tasks.json format
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "npm",
+ "script": "watch",
+ "problemMatcher": "$tsc-watch",
+ "isBackground": true,
+ "presentation": {
+ "reveal": "never"
+ },
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ }
+ ]
+}
diff --git a/packages/engine.vscode/README.md b/packages/engine.vscode/README.md
new file mode 100644
index 00000000..1e2ea222
--- /dev/null
+++ b/packages/engine.vscode/README.md
@@ -0,0 +1,34 @@
+# Cat Coding — A Webview API Sample
+
+Demonstrates VS Code's [webview API](https://code.visualstudio.com/api/extension-guides/webview). This includes:
+
+- Creating and showing a basic webview.
+- Dynamically updating a webview's content.
+- Loading local content in a webview.
+- Running scripts in a webview.
+- Sending message from an extension to a webview.
+- Sending messages from a webview to an extension.
+- Using a basic content security policy.
+- Webview lifecycle and handling dispose.
+- Saving and restoring state when the panel goes into the background.
+- Serialization and persistence across VS Code reboots.
+
+## Demo
+
+
+
+## VS Code API
+
+### `vscode` module
+
+- [`window.createWebviewPanel`](https://code.visualstudio.com/api/references/vscode-api#window.createWebviewPanel)
+- [`window.registerWebviewPanelSerializer`](https://code.visualstudio.com/api/references/vscode-api#window.registerWebviewPanelSerializer)
+
+## Running the example
+
+- Open this example in VS Code 1.47+
+- `npm install`
+- `npm run watch` or `npm run compile`
+- `F5` to start debugging
+
+Run the `Cat Coding: Start cat coding session` to create the webview.
diff --git a/packages/engine.vscode/demo.gif b/packages/engine.vscode/demo.gif
new file mode 100644
index 00000000..13b39b44
Binary files /dev/null and b/packages/engine.vscode/demo.gif differ
diff --git a/packages/engine.vscode/media/cat.gif b/packages/engine.vscode/media/cat.gif
new file mode 100644
index 00000000..8a164826
Binary files /dev/null and b/packages/engine.vscode/media/cat.gif differ
diff --git a/packages/engine.vscode/media/jsconfig.json b/packages/engine.vscode/media/jsconfig.json
new file mode 100644
index 00000000..3a2cf036
--- /dev/null
+++ b/packages/engine.vscode/media/jsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es2020",
+ "jsx": "preserve",
+ "checkJs": true,
+ "strict": true,
+ "strictFunctionTypes": true,
+ "lib": [
+ "dom"
+ ]
+ },
+ "exclude": [
+ "node_modules",
+ "**/node_modules/*"
+ ],
+ "typeAcquisition": {
+ "include": [
+ "@types/vscode-webview"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/packages/engine.vscode/media/main.js b/packages/engine.vscode/media/main.js
new file mode 100644
index 00000000..e7914da9
--- /dev/null
+++ b/packages/engine.vscode/media/main.js
@@ -0,0 +1,61 @@
+// This script will be run within the webview itself
+// It cannot access the main VS Code APIs directly.
+
+(function () {
+ const vscode = acquireVsCodeApi();
+
+ //@ts-ignore
+ function insertIframe(addr) {
+ var iframe = document.createElement('iframe')
+ iframe.setAttribute('src', addr.value);
+ iframe.setAttribute('width', '100%');
+ iframe.setAttribute('height', '650px');
+ document.body.appendChild(iframe)
+ localStorage.setItem("address", addr.value)
+ }
+
+ const address = localStorage.getItem("address")
+ if(address) {
+ insertIframe({value: address})
+ }
+
+ window.addEventListener('message', event => {
+ const message = event.data; // The json data that the extension sent
+ insertIframe("bla")
+ });
+
+ const oldState = /** @type {{ count: number} | undefined} */ (vscode.getState());
+
+ const counter = /** @type {HTMLElement} */ (document.getElementById('lines-of-code-counter'));
+ console.log('Initial state', oldState);
+
+ let currentCount = (oldState && oldState.count) || 0;
+ counter.textContent = `${currentCount}`;
+
+ setInterval(() => {
+ counter.textContent = `${currentCount++} `;
+
+ // Update state
+ vscode.setState({ count: currentCount });
+
+ // Alert the extension when the cat introduces a bug
+ if (Math.random() < Math.min(0.001 * currentCount, 0.05)) {
+ // Send a message back to the extension
+ vscode.postMessage({
+ command: 'alert',
+ text: '🐛 on line ' + currentCount
+ });
+ }
+ }, 100);
+
+ // Handle messages sent from the extension to the webview
+ window.addEventListener('message', event => {
+ const message = event.data; // The json data that the extension sent
+ switch (message.command) {
+ case 'refactor':
+ currentCount = Math.ceil(currentCount * 0.5);
+ counter.textContent = `${currentCount}`;
+ break;
+ }
+ });
+}());
diff --git a/packages/engine.vscode/media/reset.css b/packages/engine.vscode/media/reset.css
new file mode 100644
index 00000000..92d02910
--- /dev/null
+++ b/packages/engine.vscode/media/reset.css
@@ -0,0 +1,30 @@
+html {
+ box-sizing: border-box;
+ font-size: 13px;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+body,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+ol,
+ul {
+ margin: 0;
+ padding: 0;
+ font-weight: normal;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
diff --git a/packages/engine.vscode/media/vscode.css b/packages/engine.vscode/media/vscode.css
new file mode 100644
index 00000000..606bdec3
--- /dev/null
+++ b/packages/engine.vscode/media/vscode.css
@@ -0,0 +1,91 @@
+:root {
+ --container-padding: 20px;
+ --input-padding-vertical: 6px;
+ --input-padding-horizontal: 4px;
+ --input-margin-vertical: 4px;
+ --input-margin-horizontal: 0;
+}
+
+body {
+ padding: 0 var(--container-padding);
+ color: var(--vscode-foreground);
+ font-size: var(--vscode-font-size);
+ font-weight: var(--vscode-font-weight);
+ font-family: var(--vscode-font-family);
+ background-color: var(--vscode-editor-background);
+}
+
+ol,
+ul {
+ padding-left: var(--container-padding);
+}
+
+body > *,
+form > * {
+ margin-block-start: var(--input-margin-vertical);
+ margin-block-end: var(--input-margin-vertical);
+}
+
+*:focus {
+ outline-color: var(--vscode-focusBorder) !important;
+}
+
+a {
+ color: var(--vscode-textLink-foreground);
+}
+
+a:hover,
+a:active {
+ color: var(--vscode-textLink-activeForeground);
+}
+
+code {
+ font-size: var(--vscode-editor-font-size);
+ font-family: var(--vscode-editor-font-family);
+}
+
+button {
+ border: none;
+ padding: var(--input-padding-vertical) var(--input-padding-horizontal);
+ width: 100%;
+ text-align: center;
+ outline: 1px solid transparent;
+ outline-offset: 2px !important;
+ color: var(--vscode-button-foreground);
+ background: var(--vscode-button-background);
+}
+
+button:hover {
+ cursor: pointer;
+ background: var(--vscode-button-hoverBackground);
+}
+
+button:focus {
+ outline-color: var(--vscode-focusBorder);
+}
+
+button.secondary {
+ color: var(--vscode-button-secondaryForeground);
+ background: var(--vscode-button-secondaryBackground);
+}
+
+button.secondary:hover {
+ background: var(--vscode-button-secondaryHoverBackground);
+}
+
+input:not([type='checkbox']),
+textarea {
+ display: block;
+ width: 100%;
+ border: none;
+ font-family: var(--vscode-font-family);
+ padding: var(--input-padding-vertical) var(--input-padding-horizontal);
+ color: var(--vscode-input-foreground);
+ outline-color: var(--vscode-input-border);
+ background-color: var(--vscode-input-background);
+}
+
+input::placeholder,
+textarea::placeholder {
+ color: var(--vscode-input-placeholderForeground);
+}
diff --git a/packages/engine.vscode/out/extension.js b/packages/engine.vscode/out/extension.js
new file mode 100644
index 00000000..833152be
--- /dev/null
+++ b/packages/engine.vscode/out/extension.js
@@ -0,0 +1,172 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.activate = void 0;
+const vscode = require("vscode");
+const init_1 = require("./init");
+function activate(context) {
+ (0, init_1.default)(context);
+ context.subscriptions.push(vscode.commands.registerCommand('engine.dashboard.start', () => {
+ EngineDashboardPanel.createOrShow(context.extensionUri);
+ }));
+ context.subscriptions.push(vscode.commands.registerCommand('extension.refreshButtons', () => {
+ (0, init_1.default)(context);
+ }));
+ // context.subscriptions.push(
+ // vscode.commands.registerCommand('catCoding.doRefactor', () => {
+ // if (CatCodingPanel.currentPanel) {
+ // CatCodingPanel.currentPanel.doRefactor();
+ // }
+ // })
+ // );
+ if (vscode.window.registerWebviewPanelSerializer) {
+ // Make sure we register a serializer in activation event
+ vscode.window.registerWebviewPanelSerializer(EngineDashboardPanel.viewType, {
+ async deserializeWebviewPanel(webviewPanel, state) {
+ console.log(`Got state: ${state}`);
+ // Reset the webview options so we use latest uri for `localResourceRoots`.
+ webviewPanel.webview.options = getWebviewOptions(context.extensionUri);
+ EngineDashboardPanel.revive(webviewPanel, context.extensionUri);
+ }
+ });
+ }
+}
+exports.activate = activate;
+function getWebviewOptions(extensionUri) {
+ return {
+ // Enable javascript in the webview
+ enableScripts: true,
+ // And restrict the webview to only loading content from our extension's `media` directory.
+ localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'media')]
+ };
+}
+/**
+ * Manages cat coding webview panels
+ */
+class EngineDashboardPanel {
+ constructor(panel, extensionUri) {
+ this._disposables = [];
+ this._panel = panel;
+ this._extensionUri = extensionUri;
+ // Set the webview's initial html content
+ this._update();
+ // Listen for when the panel is disposed
+ // This happens when the user closes the panel or when the panel is closed programmatically
+ this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
+ // Update the content based on view changes
+ this._panel.onDidChangeViewState(e => {
+ if (this._panel.visible) {
+ this._update();
+ }
+ }, null, this._disposables);
+ // Handle messages from the webview
+ this._panel.webview.onDidReceiveMessage(message => {
+ switch (message.command) {
+ case 'alert':
+ vscode.window.showErrorMessage(message.text);
+ return;
+ }
+ }, null, this._disposables);
+ }
+ static createOrShow(extensionUri) {
+ const column = vscode.window.activeTextEditor
+ ? vscode.window.activeTextEditor.viewColumn
+ : undefined;
+ // If we already have a panel, show it.
+ if (EngineDashboardPanel.currentPanel) {
+ EngineDashboardPanel.currentPanel._panel.reveal(column);
+ return;
+ }
+ // Otherwise, create a new panel.
+ const panel = vscode.window.createWebviewPanel(EngineDashboardPanel.viewType, 'Engine Dashboard', column || vscode.ViewColumn.One, {
+ enableScripts: true,
+ retainContextWhenHidden: true,
+ localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'media')]
+ });
+ EngineDashboardPanel.currentPanel = new EngineDashboardPanel(panel, extensionUri);
+ }
+ static revive(panel, extensionUri) {
+ EngineDashboardPanel.currentPanel = new EngineDashboardPanel(panel, extensionUri);
+ }
+ doRefactor() {
+ // Send a message to the webview webview.
+ // You can send any JSON serializable data.
+ this._panel.webview.postMessage({ command: 'refactor' });
+ }
+ dispose() {
+ EngineDashboardPanel.currentPanel = undefined;
+ // Clean up our resources
+ this._panel.dispose();
+ while (this._disposables.length) {
+ const x = this._disposables.pop();
+ if (x) {
+ x.dispose();
+ }
+ }
+ }
+ _update() {
+ const webview = this._panel.webview;
+ // Vary the webview's content based on where it is located in the editor.
+ switch (this._panel.viewColumn) {
+ // case vscode.ViewColumn.Two:
+ // this._updateForCat(webview, 'Compiling Cat');
+ // return;
+ // case vscode.ViewColumn.Three:
+ // this._updateForCat(webview, 'Testing Cat');
+ // return;
+ // case vscode.ViewColumn.One:
+ default:
+ this._updateForCat(webview, 'Engine Dashboard');
+ return;
+ }
+ }
+ _updateForCat(webview, catName) {
+ this._panel.title = catName;
+ this._panel.webview.html = this._getHtmlForWebview(webview, catName);
+ }
+ _getHtmlForWebview(webview, catGifPath) {
+ // Local path to main script run in the webview
+ const scriptPathOnDisk = vscode.Uri.joinPath(this._extensionUri, 'media', 'main.js');
+ // And the uri we use to load this script in the webview
+ const scriptUri = webview.asWebviewUri(scriptPathOnDisk);
+ // Local path to css styles
+ const styleResetPath = vscode.Uri.joinPath(this._extensionUri, 'media', 'reset.css');
+ const stylesPathMainPath = vscode.Uri.joinPath(this._extensionUri, 'media', 'vscode.css');
+ // Uri to load styles into webview
+ const stylesResetUri = webview.asWebviewUri(styleResetPath);
+ const stylesMainUri = webview.asWebviewUri(stylesPathMainPath);
+ // Use a nonce to only allow specific scripts to be run
+ const nonce = getNonce();
+ return `
+
+
+
+
+
+
+
+
+ Engine Dashboard
+
+
+
+
+ 0
+
+
+
+ `;
+ }
+}
+EngineDashboardPanel.viewType = 'engineDashboard';
+function getNonce() {
+ let text = '';
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ for (let i = 0; i < 32; i++) {
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return text;
+}
+//# sourceMappingURL=extension.js.map
\ No newline at end of file
diff --git a/packages/engine.vscode/out/extension.js.map b/packages/engine.vscode/out/extension.js.map
new file mode 100644
index 00000000..16f71005
--- /dev/null
+++ b/packages/engine.vscode/out/extension.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/engine.vscode/out/init.js b/packages/engine.vscode/out/init.js
new file mode 100644
index 00000000..15c46a38
--- /dev/null
+++ b/packages/engine.vscode/out/init.js
@@ -0,0 +1,146 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const packageJson_1 = require("./packageJson");
+const vscode = require("vscode");
+const path = require("path");
+const registerCommand = vscode.commands.registerCommand;
+const disposables = [];
+const init = async (context) => {
+ disposables.forEach(d => d.dispose());
+ const config = vscode.workspace.getConfiguration('actionButtons');
+ const defaultColor = config.get('defaultColor') || "green";
+ const cmds = config.get('commands');
+ // const reloadButton = config.get('reloadButton')
+ const loadNpmCommands = config.get('loadNpmCommands');
+ const reloadButton = true;
+ // const defaultColor = "green"
+ // const cmds: Array = [ {
+ // // "cwd": "/home/custom_folder", // Terminal initial folder ${workspaceFolder} and os user home as defaults
+ // "name": "Start Engine Dashboard",
+ // "color": "green",
+ // "singleInstance": true,
+ // "command": "yarn dashboard", // This is executed in the terminal.
+ // "tooltip": ""
+ // }]
+ const commands = [];
+ if (reloadButton !== null) {
+ loadButton({
+ command: 'extension.refreshButtons',
+ name: "Refresh commands",
+ tooltip: 'Refreshes the action buttons',
+ color: defaultColor
+ });
+ }
+ else {
+ const onCfgChange = vscode.workspace.onDidChangeConfiguration(e => {
+ if (e.affectsConfiguration('actionButtons')) {
+ vscode.commands.executeCommand('extension.refreshButtons');
+ }
+ });
+ context.subscriptions.push(onCfgChange);
+ disposables.push(onCfgChange);
+ }
+ if (cmds && cmds.length) {
+ commands.push(...cmds);
+ }
+ // if (loadNpmCommands !== false)
+ commands.push(...(await (0, packageJson_1.buildConfigFromPackageJson)(defaultColor)));
+ if (commands.length) {
+ const terminals = {};
+ commands.forEach(({ cwd, saveAll, command, name, tooltip, color, singleInstance, focus, useVsCodeApi, args }) => {
+ const vsCommand = `extension.${name.replace(' ', '')}`;
+ const disposable = registerCommand(vsCommand, async () => {
+ const vars = {
+ // - the path of the folder opened in VS Code
+ workspaceFolder: vscode.workspace.rootPath,
+ // - the name of the folder opened in VS Code without any slashes (/)
+ workspaceFolderBasename: (vscode.workspace.rootPath) ? path.basename(vscode.workspace.rootPath) : null,
+ // - the current opened file
+ file: (vscode.window.activeTextEditor) ? vscode.window.activeTextEditor.document.fileName : null,
+ // - the current opened file relative to workspaceFolder
+ relativeFile: (vscode.window.activeTextEditor && vscode.workspace.rootPath) ? path.relative(vscode.workspace.rootPath, vscode.window.activeTextEditor.document.fileName) : null,
+ // - the current opened file's basename
+ fileBasename: (vscode.window.activeTextEditor) ? path.basename(vscode.window.activeTextEditor.document.fileName) : null,
+ // - the current opened file's basename with no file extension
+ fileBasenameNoExtension: (vscode.window.activeTextEditor) ? path.parse(path.basename(vscode.window.activeTextEditor.document.fileName)).name : null,
+ // - the current opened file's dirname
+ fileDirname: (vscode.window.activeTextEditor) ? path.dirname(vscode.window.activeTextEditor.document.fileName) : null,
+ // - the current opened file's extension
+ fileExtname: (vscode.window.activeTextEditor) ? path.parse(path.basename(vscode.window.activeTextEditor.document.fileName)).ext : null,
+ // - the task runner's current working directory on startup
+ cwd: cwd || vscode.workspace.rootPath || require('os').homedir(),
+ //- the current selected line number in the active file
+ lineNumber: (vscode.window.activeTextEditor) ? vscode.window.activeTextEditor.selection.active.line + 1 : null,
+ // - the current selected text in the active file
+ selectedText: (vscode.window.activeTextEditor) ? vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection) : null,
+ // - the path to the running VS Code executable
+ execPath: process.execPath
+ };
+ if (!command) {
+ vscode.window.showErrorMessage('No command to execute for this action');
+ return;
+ }
+ if (saveAll) {
+ vscode.commands.executeCommand('workbench.action.files.saveAll');
+ }
+ if (useVsCodeApi) {
+ vscode.commands.executeCommand(command, ...(args || []));
+ }
+ else {
+ let assocTerminal = terminals[vsCommand];
+ if (!assocTerminal) {
+ assocTerminal = vscode.window.createTerminal({ name, cwd: vars.cwd });
+ terminals[vsCommand] = assocTerminal;
+ }
+ else {
+ if (singleInstance) {
+ delete terminals[vsCommand];
+ assocTerminal.dispose();
+ assocTerminal = vscode.window.createTerminal({ name, cwd: vars.cwd });
+ terminals[vsCommand] = assocTerminal;
+ }
+ else {
+ assocTerminal.sendText('clear');
+ }
+ }
+ assocTerminal.show(!focus);
+ assocTerminal.sendText(interpolateString(command, vars));
+ }
+ });
+ context.subscriptions.push(disposable);
+ disposables.push(disposable);
+ loadButton({
+ command: vsCommand,
+ name,
+ tooltip: tooltip || command,
+ color: color || defaultColor,
+ });
+ });
+ }
+ else {
+ vscode.window.setStatusBarMessage('VsCode Action Buttons: You have no run commands.', 4000);
+ }
+};
+function loadButton({ command, name, tooltip, color, }) {
+ const runButton = vscode.window.createStatusBarItem(1, 0);
+ runButton.text = name;
+ runButton.color = color;
+ runButton.tooltip = tooltip;
+ runButton.command = command;
+ runButton.show();
+ disposables.push(runButton);
+}
+function interpolateString(tpl, data) {
+ let re = /\$\{([^\}]+)\}/g, match;
+ while (match = re.exec(tpl)) {
+ let path = match[1].split('.').reverse();
+ //@ts-ignore
+ let obj = data[path.pop()];
+ while (path.length)
+ obj = obj[path.pop()];
+ tpl = tpl.replace(match[0], obj);
+ }
+ return tpl;
+}
+exports.default = init;
+//# sourceMappingURL=init.js.map
\ No newline at end of file
diff --git a/packages/engine.vscode/out/init.js.map b/packages/engine.vscode/out/init.js.map
new file mode 100644
index 00000000..5aae82a9
--- /dev/null
+++ b/packages/engine.vscode/out/init.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":";;AAAA,+CAA0D;AAC1D,iCAAgC;AAEhC,6BAA4B;AAE5B,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAA;AAEvD,MAAM,WAAW,GAAe,EAAE,CAAA;AAElC,MAAM,IAAI,GAAG,KAAK,EAAE,OAAgC,EAAE,EAAE;IACvD,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAA;IACjE,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAS,cAAc,CAAC,IAAI,OAAO,CAAA;IAClE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAgB,UAAU,CAAC,CAAA;IAClD,0DAA0D;IAC1D,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAU,iBAAiB,CAAC,CAAA;IAC9D,MAAM,YAAY,GAAG,IAAI,CAAA;IACzB,+BAA+B;IAC/B,4CAA4C;IAC5C,gHAAgH;IAChH,qCAAqC;IACrC,qBAAqB;IACrB,2BAA2B;IAC3B,qEAAqE;IACrE,iBAAiB;IACjB,KAAK;IACL,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAElC,IAAI,YAAY,KAAK,IAAI,EAAE;QAC1B,UAAU,CAAC;YACV,OAAO,EAAE,0BAA0B;YACnC,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,8BAA8B;YACvC,KAAK,EAAE,YAAY;SACnB,CAAC,CAAA;KACF;SACI;QACJ,MAAM,WAAW,GAAqB,MAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE;YACnF,IAAI,CAAC,CAAC,oBAAoB,CAAC,eAAe,CAAC,EAAE;gBAC5C,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,0BAA0B,CAAC,CAAC;aAC3D;QACF,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACvC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;KAC9B;IAED,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;QACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;KACtB;IAED,kCAAkC;IACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAA,wCAA0B,EAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAEnE,IAAI,QAAQ,CAAC,MAAM,EAAE;QACpB,MAAM,SAAS,GAAwC,EAAE,CAAA;QACzD,QAAQ,CAAC,OAAO,CACf,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAe,EAAE,EAAE;YAC3G,MAAM,SAAS,GAAG,aAAa,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAA;YAEtD,MAAM,UAAU,GAAG,eAAe,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;gBACxD,MAAM,IAAI,GAAG;oBAEZ,6CAA6C;oBAC7C,eAAe,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ;oBAE1C,qEAAqE;oBACrE,uBAAuB,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;oBAErG,4BAA4B;oBAC5B,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;oBAEhG,wDAAwD;oBACxD,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAC1F,MAAM,CAAC,SAAS,CAAC,QAAQ,EACzB,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAChD,CAAC,CAAC,CAAC,IAAI;oBAER,uCAAuC;oBACvC,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;oBAEvH,8DAA8D;oBAC9D,uBAAuB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;oBAEnJ,sCAAsC;oBACtC,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;oBAErH,wCAAwC;oBACxC,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;oBAEtI,2DAA2D;oBAC3D,GAAG,EAAE,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE;oBAEhE,uDAAuD;oBACvD,UAAU,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;oBAE9G,iDAAiD;oBACjD,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;oBAEjJ,+CAA+C;oBAC/C,QAAQ,EAAE,OAAO,CAAC,QAAQ;iBAC1B,CAAA;gBAED,IAAI,CAAC,OAAO,EAAE;oBACb,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,uCAAuC,CAAC,CAAC;oBACxE,OAAO;iBACP;gBAED,IAAI,OAAO,EAAE;oBACZ,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,gCAAgC,CAAC,CAAC;iBACjE;gBAED,IAAI,YAAY,EAAE;oBACjB,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;iBACzD;qBAAM;oBACN,IAAI,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;oBACxC,IAAI,CAAC,aAAa,EAAE;wBACnB,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;wBACtE,SAAS,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC;qBACrC;yBAAM;wBACN,IAAI,cAAc,EAAE;4BACnB,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC;4BAC5B,aAAa,CAAC,OAAO,EAAE,CAAC;4BACxB,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;4BACtE,SAAS,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC;yBACrC;6BAAM;4BACN,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;yBAChC;qBACD;oBACD,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;oBAC3B,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;iBACzD;YACF,CAAC,CAAC,CAAA;YAEF,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAEtC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAE5B,UAAU,CAAC;gBACV,OAAO,EAAE,SAAS;gBAClB,IAAI;gBACJ,OAAO,EAAE,OAAO,IAAI,OAAO;gBAC3B,KAAK,EAAE,KAAK,IAAI,YAAY;aAC5B,CAAC,CAAA;QACH,CAAC,CACD,CAAA;KACD;SAAM;QACN,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAChC,kDAAkD,EAClD,IAAI,CACJ,CAAA;KACD;AACF,CAAC,CAAA;AAED,SAAS,UAAU,CAAC,EACnB,OAAO,EACP,IAAI,EACJ,OAAO,EACP,KAAK,GACO;IACZ,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACzD,SAAS,CAAC,IAAI,GAAG,IAAI,CAAA;IACrB,SAAS,CAAC,KAAK,GAAG,KAAK,CAAA;IACvB,SAAS,CAAC,OAAO,GAAG,OAAO,CAAA;IAE3B,SAAS,CAAC,OAAO,GAAG,OAAO,CAAA;IAC3B,SAAS,CAAC,IAAI,EAAE,CAAA;IAChB,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAC5B,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW,EAAE,IAAY;IACnD,IAAI,EAAE,GAAG,iBAAiB,EAAE,KAAK,CAAC;IAClC,OAAO,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAC5B,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QACzC,YAAY;QACZ,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,MAAM;YAAE,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1C,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;KAChC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,kBAAe,IAAI,CAAA"}
\ No newline at end of file
diff --git a/packages/engine.vscode/out/packageJson.js b/packages/engine.vscode/out/packageJson.js
new file mode 100644
index 00000000..fd5fb487
--- /dev/null
+++ b/packages/engine.vscode/out/packageJson.js
@@ -0,0 +1,30 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.buildConfigFromPackageJson = exports.getPackageJson = void 0;
+const vscode_1 = require("vscode");
+const getPackageJson = async () => new Promise(resolve => {
+ const cwd = vscode_1.workspace.rootPath;
+ try {
+ const packageJson = require(`${cwd}/package.json`);
+ resolve(packageJson);
+ }
+ catch (e) {
+ resolve(undefined);
+ }
+});
+exports.getPackageJson = getPackageJson;
+const buildConfigFromPackageJson = async (defaultColor) => {
+ const pkg = await (0, exports.getPackageJson)();
+ if (!pkg) {
+ return [];
+ }
+ const { scripts } = pkg;
+ return Object.keys(scripts).map(key => ({
+ command: `npm run ${key}`,
+ color: defaultColor || 'white',
+ name: key,
+ singleInstance: true
+ }));
+};
+exports.buildConfigFromPackageJson = buildConfigFromPackageJson;
+//# sourceMappingURL=packageJson.js.map
\ No newline at end of file
diff --git a/packages/engine.vscode/out/packageJson.js.map b/packages/engine.vscode/out/packageJson.js.map
new file mode 100644
index 00000000..dce0d3d4
--- /dev/null
+++ b/packages/engine.vscode/out/packageJson.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"packageJson.js","sourceRoot":"","sources":["../src/packageJson.ts"],"names":[],"mappings":";;;AACA,mCAAkC;AAE3B,MAAM,cAAc,GAAG,KAAK,IAA8B,EAAE,CAClE,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;IACrB,MAAM,GAAG,GAAG,kBAAS,CAAC,QAAQ,CAAA;IAE9B,IAAI;QACH,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,GAAG,eAAe,CAAC,CAAA;QAElD,OAAO,CAAC,WAAW,CAAC,CAAA;KACpB;IAAC,OAAO,CAAC,EAAE;QACX,OAAO,CAAC,SAAS,CAAC,CAAA;KAClB;AACF,CAAC,CAAC,CAAA;AAXU,QAAA,cAAc,kBAWxB;AAEI,MAAM,0BAA0B,GAAG,KAAK,EAAE,YAAoB,EAAE,EAAE;IACxE,MAAM,GAAG,GAAG,MAAM,IAAA,sBAAc,GAAE,CAAA;IAClC,IAAI,CAAC,GAAG,EAAE;QACT,OAAO,EAAE,CAAA;KACT;IACD,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAA;IAEvB,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,OAAO,EAAE,WAAW,GAAG,EAAE;QACzB,KAAK,EAAE,YAAY,IAAI,OAAO;QAC9B,IAAI,EAAE,GAAG;QACT,cAAc,EAAE,IAAI;KACpB,CAAC,CAAkB,CAAA;AACrB,CAAC,CAAA;AAbY,QAAA,0BAA0B,8BAatC"}
\ No newline at end of file
diff --git a/packages/engine.vscode/out/types.js b/packages/engine.vscode/out/types.js
new file mode 100644
index 00000000..11e638d1
--- /dev/null
+++ b/packages/engine.vscode/out/types.js
@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/packages/engine.vscode/out/types.js.map b/packages/engine.vscode/out/types.js.map
new file mode 100644
index 00000000..c768b790
--- /dev/null
+++ b/packages/engine.vscode/out/types.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/packages/engine.vscode/package.json b/packages/engine.vscode/package.json
new file mode 100644
index 00000000..4e67d69d
--- /dev/null
+++ b/packages/engine.vscode/package.json
@@ -0,0 +1,144 @@
+{
+ "name": "@c11/engine.vscode",
+ "description": "Visual Studio Code for @c11/engine.dashboard",
+ "version": "0.0.1",
+ "private": true,
+ "license": "MIT",
+ "engines": {
+ "vscode": "^1.47.0"
+ },
+ "categories": [
+ "Other"
+ ],
+ "activationEvents": [
+ "*"
+ ],
+ "main": "./out/extension.js",
+ "contributes": {
+ "commands": [
+ {
+ "command": "engine.dashboard.start",
+ "title": "Start engine dashboard",
+ "category": "Engine Dashboard"
+ },
+ {
+ "command": "extension.refreshButtons",
+ "title": "Refresh Action Buttons"
+ }
+ ],
+ "configuration": {
+ "type": "object",
+ "title": "VsCode Action Buttons",
+ "properties": {
+ "actionButtons": {
+ "type": "object",
+ "additionalProperties": false,
+ "default": {
+ "commands": [],
+ "defaultColor": "white",
+ "reloadButton": "↻",
+ "loadNpmCommands": false
+ },
+ "properties": {
+ "commands": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "name",
+ "command"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "markdownDescription": "Name of the action button"
+ },
+ "saveAll": {
+ "type": "boolean",
+ "markdownDescription": "Save all open files before execute command"
+ },
+ "command": {
+ "type": "string",
+ "markdownDescription": "Command to execute when action is activated.\n\nIf `useVsCodeApi` is `true`, this is the VS Code command to execute. Otherwise, this specifies the command to execute in the terminal"
+ },
+ "tooltip": {
+ "type": "string",
+ "markdownDescription": "Tooltip text to display when hovering over the button"
+ },
+ "color": {
+ "type": "string",
+ "markdownDescription": "Specifies the action button text color"
+ },
+ "cwd": {
+ "type": "string",
+ "markdownDescription": "Start directory when executing terminal command\n\nOnly valid when `useVsCodeApi` is `false`"
+ },
+ "singleInstance": {
+ "type": "boolean",
+ "default": false,
+ "markdownDescription": "Reopen associated terminal each time this action is activated\n\nOnly valid when `useVsCodeApi` is `false`"
+ },
+ "focus": {
+ "type": "boolean",
+ "default": false,
+ "markdownDescription": "Focus the terminal after executing the command.\n\nOnly valid when `useVsCodeApi` is `false`"
+ },
+ "useVsCodeApi": {
+ "type": "boolean",
+ "default": false,
+ "markdownDescription": "Specifies whether to execute a VS Code command or terminal command"
+ },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "markdownDescription": "List of arguments passed to VS Code command\n\nOnly valid when `useVsCodeApi` is `true`"
+ }
+ }
+ }
+ },
+ "defaultColor": {
+ "type": "string",
+ "required": false,
+ "default": "white",
+ "markdownDescription": "Default color to use for action button text"
+ },
+ "reloadButton": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "required": false,
+ "default": "↻",
+ "markdownDescription": "Reload button text. If `null`, button is disabled"
+ },
+ "loadNpmCommands": {
+ "type": "boolean",
+ "required": false,
+ "default": false,
+ "markdownDescription": "Specifies whether to automatically generate buttons from npm commands listed in `package.json`"
+ }
+ }
+ }
+ }
+ }
+ },
+ "scripts": {
+ "vscode:prepublish": "npm run compile",
+ "compile": "tsc -p ./",
+ "lint": "eslint . --ext .ts,.tsx",
+ "watch": "tsc -w -p ./"
+ },
+ "devDependencies": {
+ "@types/node": "^16.11.7",
+ "@types/vscode": "^1.47.0",
+ "@types/vscode-webview": "^1.57.0",
+ "@typescript-eslint/eslint-plugin": "^5.30.0",
+ "@typescript-eslint/parser": "^5.30.0",
+ "eslint": "^8.13.0",
+ "typescript": "^4.7.2"
+ }
+}
\ No newline at end of file
diff --git a/packages/engine.vscode/src/bla.html b/packages/engine.vscode/src/bla.html
new file mode 100644
index 00000000..759ab09a
--- /dev/null
+++ b/packages/engine.vscode/src/bla.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ Engine Dashboard
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/engine.vscode/src/extension.ts b/packages/engine.vscode/src/extension.ts
new file mode 100644
index 00000000..a84b0125
--- /dev/null
+++ b/packages/engine.vscode/src/extension.ts
@@ -0,0 +1,227 @@
+import * as vscode from 'vscode';
+import init from './init'
+
+export function activate(context: vscode.ExtensionContext) {
+ init(context)
+
+ context.subscriptions.push(
+ vscode.commands.registerCommand('engine.dashboard.start', () => {
+ EngineDashboardPanel.createOrShow(context.extensionUri);
+ })
+ );
+
+ context.subscriptions.push(vscode.commands.registerCommand(
+ 'extension.refreshButtons',
+ () => {
+ init(context)
+ }
+ ))
+
+ // context.subscriptions.push(
+ // vscode.commands.registerCommand('catCoding.doRefactor', () => {
+ // if (CatCodingPanel.currentPanel) {
+ // CatCodingPanel.currentPanel.doRefactor();
+ // }
+ // })
+ // );
+
+ if (vscode.window.registerWebviewPanelSerializer) {
+ // Make sure we register a serializer in activation event
+ vscode.window.registerWebviewPanelSerializer(EngineDashboardPanel.viewType, {
+ async deserializeWebviewPanel(webviewPanel: vscode.WebviewPanel, state: any) {
+ console.log(`Got state: ${state}`);
+ // Reset the webview options so we use latest uri for `localResourceRoots`.
+ webviewPanel.webview.options = getWebviewOptions(context.extensionUri);
+ EngineDashboardPanel.revive(webviewPanel, context.extensionUri);
+ }
+ });
+ }
+}
+
+function getWebviewOptions(extensionUri: vscode.Uri): vscode.WebviewOptions {
+ return {
+ // Enable javascript in the webview
+ enableScripts: true,
+
+ // And restrict the webview to only loading content from our extension's `media` directory.
+ localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'media')]
+ };
+}
+
+/**
+ * Manages cat coding webview panels
+ */
+class EngineDashboardPanel {
+ /**
+ * Track the currently panel. Only allow a single panel to exist at a time.
+ */
+ public static currentPanel: EngineDashboardPanel | undefined;
+
+ public static readonly viewType = 'engineDashboard';
+
+ private readonly _panel: vscode.WebviewPanel;
+ private readonly _extensionUri: vscode.Uri;
+ private _disposables: vscode.Disposable[] = [];
+
+ public static createOrShow(extensionUri: vscode.Uri) {
+ const column = vscode.window.activeTextEditor
+ ? vscode.window.activeTextEditor.viewColumn
+ : undefined;
+
+ // If we already have a panel, show it.
+ if (EngineDashboardPanel.currentPanel) {
+ EngineDashboardPanel.currentPanel._panel.reveal(column);
+ return;
+ }
+
+ // Otherwise, create a new panel.
+ const panel = vscode.window.createWebviewPanel(
+ EngineDashboardPanel.viewType,
+ 'Engine Dashboard',
+ column || vscode.ViewColumn.One,
+ {
+ enableScripts: true,
+ retainContextWhenHidden: true,
+ localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'media')]
+ }
+ );
+
+ EngineDashboardPanel.currentPanel = new EngineDashboardPanel(panel, extensionUri);
+ }
+
+ public static revive(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
+ EngineDashboardPanel.currentPanel = new EngineDashboardPanel(panel, extensionUri);
+ }
+
+ private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
+ this._panel = panel;
+ this._extensionUri = extensionUri;
+
+ // Set the webview's initial html content
+ this._update();
+
+ // Listen for when the panel is disposed
+ // This happens when the user closes the panel or when the panel is closed programmatically
+ this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
+
+ // Update the content based on view changes
+ this._panel.onDidChangeViewState(
+ e => {
+ if (this._panel.visible) {
+ this._update();
+ }
+ },
+ null,
+ this._disposables
+ );
+
+ // Handle messages from the webview
+ this._panel.webview.onDidReceiveMessage(
+ message => {
+ switch (message.command) {
+ case 'alert':
+ vscode.window.showErrorMessage(message.text);
+ return;
+ }
+ },
+ null,
+ this._disposables
+ );
+ }
+
+ public doRefactor() {
+ // Send a message to the webview webview.
+ // You can send any JSON serializable data.
+ this._panel.webview.postMessage({ command: 'refactor' });
+ }
+
+ public dispose() {
+ EngineDashboardPanel.currentPanel = undefined;
+
+ // Clean up our resources
+ this._panel.dispose();
+
+ while (this._disposables.length) {
+ const x = this._disposables.pop();
+ if (x) {
+ x.dispose();
+ }
+ }
+ }
+
+ private _update() {
+ const webview = this._panel.webview;
+
+ // Vary the webview's content based on where it is located in the editor.
+ switch (this._panel.viewColumn) {
+ // case vscode.ViewColumn.Two:
+ // this._updateForCat(webview, 'Compiling Cat');
+ // return;
+
+ // case vscode.ViewColumn.Three:
+ // this._updateForCat(webview, 'Testing Cat');
+ // return;
+
+ // case vscode.ViewColumn.One:
+ default:
+ this._updateForCat(webview, 'Engine Dashboard');
+ return;
+ }
+ }
+
+ private _updateForCat(webview: vscode.Webview, catName: string) {
+ this._panel.title = catName;
+ this._panel.webview.html = this._getHtmlForWebview(webview, catName);
+ }
+
+ private _getHtmlForWebview(webview: vscode.Webview, catGifPath: string) {
+ // Local path to main script run in the webview
+ const scriptPathOnDisk = vscode.Uri.joinPath(this._extensionUri, 'media', 'main.js');
+
+ // And the uri we use to load this script in the webview
+ const scriptUri = webview.asWebviewUri(scriptPathOnDisk);
+
+ // Local path to css styles
+ const styleResetPath = vscode.Uri.joinPath(this._extensionUri, 'media', 'reset.css');
+ const stylesPathMainPath = vscode.Uri.joinPath(this._extensionUri, 'media', 'vscode.css');
+
+ // Uri to load styles into webview
+ const stylesResetUri = webview.asWebviewUri(styleResetPath);
+ const stylesMainUri = webview.asWebviewUri(stylesPathMainPath);
+
+ // Use a nonce to only allow specific scripts to be run
+ const nonce = getNonce();
+
+ return `
+
+
+
+
+
+
+
+
+ Engine Dashboard
+
+
+
+
+ 0
+
+
+
+ `;
+ }
+}
+
+function getNonce() {
+ let text = '';
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ for (let i = 0; i < 32; i++) {
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return text;
+}
diff --git a/packages/engine.vscode/src/init.ts b/packages/engine.vscode/src/init.ts
new file mode 100644
index 00000000..62df622b
--- /dev/null
+++ b/packages/engine.vscode/src/init.ts
@@ -0,0 +1,182 @@
+import { buildConfigFromPackageJson } from './packageJson'
+import * as vscode from 'vscode'
+import { ButtonOpts, CommandOpts } from './types'
+import * as path from 'path'
+
+const registerCommand = vscode.commands.registerCommand
+
+const disposables: Array = []
+
+const init = async (context: vscode.ExtensionContext) => {
+ disposables.forEach(d => d.dispose())
+ const config = vscode.workspace.getConfiguration('actionButtons')
+ const defaultColor = config.get('defaultColor') || "green"
+ const cmds = config.get('commands')
+ // const reloadButton = config.get('reloadButton')
+ const loadNpmCommands = config.get('loadNpmCommands')
+ const reloadButton = true
+ // const defaultColor = "green"
+ // const cmds: Array = [ {
+ // // "cwd": "/home/custom_folder", // Terminal initial folder ${workspaceFolder} and os user home as defaults
+ // "name": "Start Engine Dashboard",
+ // "color": "green",
+ // "singleInstance": true,
+ // "command": "yarn dashboard", // This is executed in the terminal.
+ // "tooltip": ""
+ // }]
+ const commands: CommandOpts[] = []
+
+ if (reloadButton !== null) {
+ loadButton({
+ command: 'extension.refreshButtons',
+ name: "Refresh commands",
+ tooltip: 'Refreshes the action buttons',
+ color: defaultColor
+ })
+ }
+ else {
+ const onCfgChange:vscode.Disposable = vscode.workspace.onDidChangeConfiguration(e => {
+ if (e.affectsConfiguration('actionButtons')) {
+ vscode.commands.executeCommand('extension.refreshButtons');
+ }
+ });
+ context.subscriptions.push(onCfgChange)
+ disposables.push(onCfgChange);
+ }
+
+ if (cmds && cmds.length) {
+ commands.push(...cmds)
+ }
+
+ // if (loadNpmCommands !== false)
+ commands.push(...(await buildConfigFromPackageJson(defaultColor)))
+
+ if (commands.length) {
+ const terminals: { [name: string]: vscode.Terminal } = {}
+ commands.forEach(
+ ({ cwd, saveAll, command, name, tooltip, color, singleInstance, focus, useVsCodeApi, args }: CommandOpts) => {
+ const vsCommand = `extension.${name.replace(' ', '')}`
+
+ const disposable = registerCommand(vsCommand, async () => {
+ const vars = {
+
+ // - the path of the folder opened in VS Code
+ workspaceFolder: vscode.workspace.rootPath,
+
+ // - the name of the folder opened in VS Code without any slashes (/)
+ workspaceFolderBasename: (vscode.workspace.rootPath)? path.basename(vscode.workspace.rootPath) : null,
+
+ // - the current opened file
+ file: (vscode.window.activeTextEditor) ? vscode.window.activeTextEditor.document.fileName : null,
+
+ // - the current opened file relative to workspaceFolder
+ relativeFile: (vscode.window.activeTextEditor && vscode.workspace.rootPath) ? path.relative(
+ vscode.workspace.rootPath,
+ vscode.window.activeTextEditor.document.fileName
+ ) : null,
+
+ // - the current opened file's basename
+ fileBasename: (vscode.window.activeTextEditor) ? path.basename(vscode.window.activeTextEditor.document.fileName) : null,
+
+ // - the current opened file's basename with no file extension
+ fileBasenameNoExtension: (vscode.window.activeTextEditor) ? path.parse(path.basename(vscode.window.activeTextEditor.document.fileName)).name : null,
+
+ // - the current opened file's dirname
+ fileDirname: (vscode.window.activeTextEditor) ? path.dirname(vscode.window.activeTextEditor.document.fileName) : null,
+
+ // - the current opened file's extension
+ fileExtname: (vscode.window.activeTextEditor) ? path.parse(path.basename(vscode.window.activeTextEditor.document.fileName)).ext : null,
+
+ // - the task runner's current working directory on startup
+ cwd: cwd || vscode.workspace.rootPath || require('os').homedir(),
+
+ //- the current selected line number in the active file
+ lineNumber: (vscode.window.activeTextEditor) ? vscode.window.activeTextEditor.selection.active.line + 1 : null,
+
+ // - the current selected text in the active file
+ selectedText: (vscode.window.activeTextEditor) ? vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection) : null,
+
+ // - the path to the running VS Code executable
+ execPath: process.execPath
+ }
+
+ if (!command) {
+ vscode.window.showErrorMessage('No command to execute for this action');
+ return;
+ }
+
+ if (saveAll) {
+ vscode.commands.executeCommand('workbench.action.files.saveAll');
+ }
+
+ if (useVsCodeApi) {
+ vscode.commands.executeCommand(command, ...(args || []));
+ } else {
+ let assocTerminal = terminals[vsCommand]
+ if (!assocTerminal) {
+ assocTerminal = vscode.window.createTerminal({ name, cwd: vars.cwd });
+ terminals[vsCommand] = assocTerminal;
+ } else {
+ if (singleInstance) {
+ delete terminals[vsCommand];
+ assocTerminal.dispose();
+ assocTerminal = vscode.window.createTerminal({ name, cwd: vars.cwd });
+ terminals[vsCommand] = assocTerminal;
+ } else {
+ assocTerminal.sendText('clear');
+ }
+ }
+ assocTerminal.show(!focus);
+ assocTerminal.sendText(interpolateString(command, vars));
+ }
+ })
+
+ context.subscriptions.push(disposable)
+
+ disposables.push(disposable)
+
+ loadButton({
+ command: vsCommand,
+ name,
+ tooltip: tooltip || command,
+ color: color || defaultColor,
+ })
+ }
+ )
+ } else {
+ vscode.window.setStatusBarMessage(
+ 'VsCode Action Buttons: You have no run commands.',
+ 4000
+ )
+ }
+}
+
+function loadButton({
+ command,
+ name,
+ tooltip,
+ color,
+}: ButtonOpts) {
+ const runButton = vscode.window.createStatusBarItem(1, 0)
+ runButton.text = name
+ runButton.color = color
+ runButton.tooltip = tooltip
+
+ runButton.command = command
+ runButton.show()
+ disposables.push(runButton)
+}
+
+function interpolateString(tpl: string, data: object): string {
+ let re = /\$\{([^\}]+)\}/g, match;
+ while (match = re.exec(tpl)) {
+ let path = match[1].split('.').reverse();
+ //@ts-ignore
+ let obj = data[path.pop()];
+ while (path.length) obj = obj[path.pop()];
+ tpl = tpl.replace(match[0], obj)
+ }
+ return tpl;
+}
+
+export default init
\ No newline at end of file
diff --git a/packages/engine.vscode/src/packageJson.ts b/packages/engine.vscode/src/packageJson.ts
new file mode 100644
index 00000000..91c8a814
--- /dev/null
+++ b/packages/engine.vscode/src/packageJson.ts
@@ -0,0 +1,30 @@
+import { CommandOpts } from './types'
+import { workspace } from 'vscode'
+
+export const getPackageJson = async (): Promise =>
+ new Promise(resolve => {
+ const cwd = workspace.rootPath
+
+ try {
+ const packageJson = require(`${cwd}/package.json`)
+
+ resolve(packageJson)
+ } catch (e) {
+ resolve(undefined)
+ }
+ })
+
+export const buildConfigFromPackageJson = async (defaultColor: string) => {
+ const pkg = await getPackageJson()
+ if (!pkg) {
+ return []
+ }
+ const { scripts } = pkg
+
+ return Object.keys(scripts).map(key => ({
+ command: `npm run ${key}`,
+ color: defaultColor || 'white',
+ name: key,
+ singleInstance: true
+ })) as CommandOpts[]
+}
\ No newline at end of file
diff --git a/packages/engine.vscode/src/types.ts b/packages/engine.vscode/src/types.ts
new file mode 100644
index 00000000..6bb6d587
--- /dev/null
+++ b/packages/engine.vscode/src/types.ts
@@ -0,0 +1,19 @@
+export interface CommandOpts {
+ cwd?: string
+ saveAll?: boolean
+ command: string
+ singleInstance?: boolean
+ name: string
+ tooltip: string
+ color: string
+ focus?: boolean
+ useVsCodeApi?: boolean
+ args?: string[]
+}
+
+export interface ButtonOpts {
+ command: string
+ tooltip: string
+ name: string
+ color: string
+}
\ No newline at end of file
diff --git a/packages/engine.vscode/tsconfig.json b/packages/engine.vscode/tsconfig.json
new file mode 100644
index 00000000..9a3f5254
--- /dev/null
+++ b/packages/engine.vscode/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es2020",
+ "lib": ["es2020"],
+ "outDir": "out",
+ "sourceMap": true,
+ "strict": true,
+ "rootDir": "src"
+ },
+ "exclude": ["node_modules", ".vscode-test"]
+}