diff --git a/CHANGELOG.md b/CHANGELOG.md index cae0421..eaeecdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 > **Note**: odd version numbers, for example, `0.13.0`, are not included in this changelog. They are used to test the new features and fixes before the final release. +## [0.27.0] - Unreleased + +### Added: + +- Task provider: Added `devproxy` task provider to run Dev Proxy commands +- Problem watcher: Added `$devproxy-watch` +- Snippets: Added `devproxy-task-start` - Start Dev Proxy VS Code Task +- Snippets: Added `devproxy-task-stop` - Stop Dev Proxy VS Code Task + ## [0.26.3] - 2025-06-27 ### Fixed: @@ -56,7 +65,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Snippets: Added `devproxy-plugin-openai-telemetry-config` - OpenAITelemetryPlugin config section - Snippets: Added `devproxy-plugin-prices-file` - OpenAITelemetryPlugin telemetry prices file - Snippets: Added `devproxy-plugin-price` - OpenAITelemetryPlugin telemetry model price -- Code ### Changed: diff --git a/README.md b/README.md index 2bb1b32..3ba5f81 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,10 @@ Shown when the active document is a Dev Proxy configuration file - New version detection - Upgrade Dev Proxy +### Problem Watcher + +- `$devproxy-watch` - Used for background tasks to tell VS Code when Dev Proxy has started + ### Settings - `dev-proxy-toolkit.version` - Determines the version to use when Dev Proxy and Dev Proxy Beta are installed side by side. Can be `stable` (default) or `beta`. @@ -169,6 +173,8 @@ Shown when the active document is a Dev Proxy configuration file | `devproxy-reporter-json` | JsonReporter instance | | `devproxy-reporter-markdown` | MarkdownReporter instance | | `devproxy-reporter-plain-text` | PlainTextReporter instance | +| `devproxy-task-start` | Start Dev Proxy VS Code Task | +| `devproxy-task-stop` | Stop Dev Proxy VS Code Task | ### Status Bar @@ -178,3 +184,30 @@ Shown when the active document is a Dev Proxy configuration file - Display radio tower when Dev Proxy is running - Display error is Dev Proxy is not installed - Upgrade Dev Proxy progress + +### Task Provider + +- Start Dev Proxy Task +- Stop Dev Proxy Task + +Example `.vscode/tasks.json`: + +```json +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Dev Proxy", + "type": "devproxy", + "command": "start", + "isBackground": true, + "problemMatcher": "$devproxy-watch" + }, + { + "label": "Stop Dev Proxy", + "type": "devproxy", + "command": "stop" + } + ] +} +``` diff --git a/package-lock.json b/package-lock.json index f624f7e..05afc34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dev-proxy-toolkit", - "version": "0.26.3", + "version": "0.27.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dev-proxy-toolkit", - "version": "0.26.3", + "version": "0.27.0", "dependencies": { "json-to-ast": "2.1.0", "semver": "7.7.2" diff --git a/package.json b/package.json index 6bdb5f0..5ff83c4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "dev-proxy-toolkit", "displayName": "Dev Proxy Toolkit", "description": "Makes it easy to create and update Dev Proxy configuration files.", - "version": "0.26.3", + "version": "0.27.0", "publisher": "garrytrinder", "engines": { "vscode": "^1.101.0" @@ -131,6 +131,35 @@ } ] }, + "taskDefinitions": [ + { + "type": "devproxy", + "required": [ + "command" + ], + "properties": { + "command": { + "type": "string", + "enum": [ + "start", + "stop" + ], + "description": "The Dev Proxy command to execute" + }, + "configFile": { + "type": "string", + "description": "Path to the Dev Proxy configuration file" + }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional command-line arguments" + } + } + } + ], "snippets": [ { "language": "json", @@ -173,7 +202,34 @@ "description": "The port number used to communicate with Dev Proxy API." } } - } + }, + "problemMatchers": [ + { + "name": "devproxy-watch", + "label": "Dev Proxy Background Task", + "owner": "dev-proxy-toolkit", + "source": "Dev Proxy", + "fileLocation": "absolute", + "pattern": [ + { + "regexp": "^\\[\\d{2}:\\d{2}:\\d{2}\\]\\s+(error|warn)\\s+(.*)$", + "severity": 1, + "message": 2 + }, + { + "regexp": "^\\s+at\\s+(.+):(\\d+):(\\d+)$", + "file": 1, + "line": 2, + "column": 3 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": "^.*Starting Dev Proxy.*$", + "endsPattern": "^.*(?:Dev Proxy is ready|Press CTRL\\+C to stop Dev Proxy).*$" + } + } + ] }, "preview": false, "pricing": "Free", diff --git a/src/extension.ts b/src/extension.ts index 4943639..5085a83 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -8,6 +8,7 @@ import { registerCodeActions } from './codeactions'; import { updateGlobalState } from './state'; import { VersionPreference } from './enums'; import { registerMcpServer } from './mcp'; +import { registerTaskProvider } from './taskprovider'; export const activate = async (context: vscode.ExtensionContext): Promise => { @@ -24,6 +25,7 @@ export const activate = async (context: vscode.ExtensionContext): Promise | undefined { + return this.getDevProxyTasks(); + } + + resolveTask(task: vscode.Task): vscode.Task | undefined { + const definition = task.definition as DevProxyTaskDefinition; + + if (definition.type !== DevProxyTaskProvider.DevProxyType) { + return undefined; + } + + return this.createTaskFromDefinition(definition); + } + + private async getDevProxyTasks(): Promise { + const tasks: vscode.Task[] = []; + + tasks.push(this.createStartTask()); + tasks.push(this.createStopTask()); + + return tasks; + } + + private createStartTask(): vscode.Task { + const definition: DevProxyTaskDefinition = { + type: 'devproxy', + command: 'start', + label: 'Start Dev Proxy' + }; + + return this.createTaskFromDefinition(definition); + } + + private createStopTask(): vscode.Task { + const definition: DevProxyTaskDefinition = { + type: 'devproxy', + command: 'stop', + label: 'Stop Dev Proxy' + }; + + return this.createTaskFromDefinition(definition); + } + + private createTaskFromDefinition(definition: DevProxyTaskDefinition): vscode.Task { + let execution: vscode.ShellExecution; + + if (definition.command === 'start') { + const args = this.buildArgumentsFromDefinition(definition); + execution = new vscode.ShellExecution(this.devProxyExe, args, { + cwd: '${workspaceFolder}' + }); + } else if (definition.command === 'stop') { + // Use curl to stop Dev Proxy via API + const configuration = vscode.workspace.getConfiguration('dev-proxy-toolkit'); + const apiPort = configuration.get('apiPort', 8897); + execution = new vscode.ShellExecution('curl', [ + '-X', 'POST', + `http://localhost:${apiPort}/proxy/stopproxy` + ]); + } else { + throw new Error(`Unsupported command: ${definition.command}`); + } + + const task = new vscode.Task( + definition, + vscode.TaskScope.Workspace, + definition.label || `Dev Proxy: ${definition.command}`, + DevProxyTaskProvider.DevProxyType, + execution, + definition.command === 'start' ? ['$devproxy-watch'] : [] + ); + + // Configure task properties based on command + if (definition.command === 'start') { + task.group = vscode.TaskGroup.Build; + task.isBackground = true; + task.presentationOptions = { + echo: true, + reveal: vscode.TaskRevealKind.Always, + focus: false, + panel: vscode.TaskPanelKind.Dedicated, + showReuseMessage: true, + clear: false + }; + } else if (definition.command === 'stop') { + task.group = vscode.TaskGroup.Build; + task.presentationOptions = { + echo: false, + reveal: vscode.TaskRevealKind.Silent, + focus: false + }; + } + + return task; + } + + private buildArgumentsFromDefinition(definition: DevProxyTaskDefinition): string[] { + const args: string[] = []; + + // Handle specific properties + if (definition.configFile) { + args.push('--config-file', definition.configFile); + } + + // Add any additional args + if (definition.args) { + args.push(...definition.args); + } + + return args; + } +} + +export const registerTaskProvider = (context: vscode.ExtensionContext) => { + const provider = new DevProxyTaskProvider(context); + context.subscriptions.push( + vscode.tasks.registerTaskProvider(DevProxyTaskProvider.DevProxyType, provider) + ); +};