Skip to content

Commit 8df997d

Browse files
committed
Add task provider. Closes #136
Closes #136
1 parent 48e3ef4 commit 8df997d

File tree

6 files changed

+266
-2
lines changed

6 files changed

+266
-2
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
> **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.
99
10+
## [0.27.0] - Unreleased
11+
12+
### Added:
13+
14+
- Task provider: Added `devproxy` task provider to run Dev Proxy commands
15+
- Problem watcher: Added `$devproxy-watch`
16+
- Snippets: Added `devproxy-task-start` - Start Dev Proxy VS Code Task
17+
- Snippets: Added `devproxy-task-stop` - Stop Dev Proxy VS Code Task
18+
1019
## [0.26.3] - 2025-06-27
1120

1221
### Fixed:
@@ -56,7 +65,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5665
- Snippets: Added `devproxy-plugin-openai-telemetry-config` - OpenAITelemetryPlugin config section
5766
- Snippets: Added `devproxy-plugin-prices-file` - OpenAITelemetryPlugin telemetry prices file
5867
- Snippets: Added `devproxy-plugin-price` - OpenAITelemetryPlugin telemetry model price
59-
- Code
6068

6169
### Changed:
6270

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ Shown when the active document is a Dev Proxy configuration file
6969
- New version detection
7070
- Upgrade Dev Proxy
7171

72+
### Problem Watcher
73+
74+
- `$devproxy-watch` - Used for background tasks to tell VS Code when Dev Proxy has started
75+
7276
### Settings
7377

7478
- `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
169173
| `devproxy-reporter-json` | JsonReporter instance |
170174
| `devproxy-reporter-markdown` | MarkdownReporter instance |
171175
| `devproxy-reporter-plain-text` | PlainTextReporter instance |
176+
| `devproxy-task-start` | Start Dev Proxy VS Code Task |
177+
| `devproxy-task-stop` | Stop Dev Proxy VS Code Task |
172178

173179
### Status Bar
174180

@@ -178,3 +184,30 @@ Shown when the active document is a Dev Proxy configuration file
178184
- Display radio tower when Dev Proxy is running
179185
- Display error is Dev Proxy is not installed
180186
- Upgrade Dev Proxy progress
187+
188+
### Task Provider
189+
190+
- Start Dev Proxy Task
191+
- Stop Dev Proxy Task
192+
193+
Example `.vscode/tasks.json`:
194+
195+
```json
196+
{
197+
"version": "2.0.0",
198+
"tasks": [
199+
{
200+
"label": "Start Dev Proxy",
201+
"type": "devproxy",
202+
"command": "start",
203+
"isBackground": true,
204+
"problemMatcher": "$devproxy-watch"
205+
},
206+
{
207+
"label": "Stop Dev Proxy",
208+
"type": "devproxy",
209+
"command": "stop"
210+
}
211+
]
212+
}
213+
```

package.json

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,35 @@
131131
}
132132
]
133133
},
134+
"taskDefinitions": [
135+
{
136+
"type": "devproxy",
137+
"required": [
138+
"command"
139+
],
140+
"properties": {
141+
"command": {
142+
"type": "string",
143+
"enum": [
144+
"start",
145+
"stop"
146+
],
147+
"description": "The Dev Proxy command to execute"
148+
},
149+
"configFile": {
150+
"type": "string",
151+
"description": "Path to the Dev Proxy configuration file"
152+
},
153+
"args": {
154+
"type": "array",
155+
"items": {
156+
"type": "string"
157+
},
158+
"description": "Additional command-line arguments"
159+
}
160+
}
161+
}
162+
],
134163
"snippets": [
135164
{
136165
"language": "json",
@@ -173,7 +202,34 @@
173202
"description": "The port number used to communicate with Dev Proxy API."
174203
}
175204
}
176-
}
205+
},
206+
"problemMatchers": [
207+
{
208+
"name": "devproxy-watch",
209+
"label": "Dev Proxy Background Task",
210+
"owner": "dev-proxy-toolkit",
211+
"source": "Dev Proxy",
212+
"fileLocation": "absolute",
213+
"pattern": [
214+
{
215+
"regexp": "^\\[\\d{2}:\\d{2}:\\d{2}\\]\\s+(error|warn)\\s+(.*)$",
216+
"severity": 1,
217+
"message": 2
218+
},
219+
{
220+
"regexp": "^\\s+at\\s+(.+):(\\d+):(\\d+)$",
221+
"file": 1,
222+
"line": 2,
223+
"column": 3
224+
}
225+
],
226+
"background": {
227+
"activeOnStart": true,
228+
"beginsPattern": "^.*Starting Dev Proxy.*$",
229+
"endsPattern": "^.*(?:Dev Proxy is ready|Press CTRL\\+C to stop Dev Proxy).*$"
230+
}
231+
}
232+
]
177233
},
178234
"preview": false,
179235
"pricing": "Free",

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { registerCodeActions } from './codeactions';
88
import { updateGlobalState } from './state';
99
import { VersionPreference } from './enums';
1010
import { registerMcpServer } from './mcp';
11+
import { registerTaskProvider } from './taskprovider';
1112

1213
export const activate = async (context: vscode.ExtensionContext): Promise<vscode.ExtensionContext> => {
1314

@@ -24,6 +25,7 @@ export const activate = async (context: vscode.ExtensionContext): Promise<vscode
2425
registerCodeLens(context);
2526
registerCommands(context, configuration);
2627
registerMcpServer(context);
28+
registerTaskProvider(context);
2729

2830
const notification = handleStartNotification(context);
2931
processNotification(notification);

src/snippets.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,5 +1086,29 @@
10861086
"}"
10871087
],
10881088
"description": "PlainTextReporter instance"
1089+
},
1090+
"StartTask": {
1091+
"prefix": "devproxy-task-start",
1092+
"body": [
1093+
"{",
1094+
"\t\"label\": \"Start Dev Proxy\",",
1095+
"\t\"type\": \"devproxy\",",
1096+
"\t\"command\": \"start\",",
1097+
"\t\"isBackground\": true,",
1098+
"\t\"problemMatcher\": \"\\$devproxy-watch\"",
1099+
"}"
1100+
],
1101+
"description": "Start Dev Proxy VS Code Task"
1102+
},
1103+
"StopTask": {
1104+
"prefix": "devproxy-task-stop",
1105+
"body": [
1106+
"{",
1107+
"\t\"label\": \"Stop Dev Proxy\",",
1108+
"\t\"type\": \"devproxy\",",
1109+
"\t\"command\": \"stop\"",
1110+
"}"
1111+
],
1112+
"description": "Stop Dev Proxy VS Code Task"
10891113
}
10901114
}

src/taskprovider.ts

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import * as vscode from 'vscode';
2+
import { getDevProxyExe } from './detect';
3+
import { VersionPreference } from './enums';
4+
5+
interface DevProxyTaskDefinition extends vscode.TaskDefinition {
6+
type: 'devproxy';
7+
command: 'start' | 'stop';
8+
configFile?: string;
9+
args?: string[];
10+
label?: string;
11+
}
12+
13+
export class DevProxyTaskProvider implements vscode.TaskProvider {
14+
static DevProxyType = 'devproxy';
15+
private devProxyExe: string;
16+
17+
constructor(private context: vscode.ExtensionContext) {
18+
const configuration = vscode.workspace.getConfiguration('dev-proxy-toolkit');
19+
const versionPreference = configuration.get('version') as VersionPreference;
20+
this.devProxyExe = getDevProxyExe(versionPreference);
21+
}
22+
23+
provideTasks(): Thenable<vscode.Task[]> | undefined {
24+
return this.getDevProxyTasks();
25+
}
26+
27+
resolveTask(task: vscode.Task): vscode.Task | undefined {
28+
const definition = task.definition as DevProxyTaskDefinition;
29+
30+
if (definition.type !== DevProxyTaskProvider.DevProxyType) {
31+
return undefined;
32+
}
33+
34+
return this.createTaskFromDefinition(definition);
35+
}
36+
37+
private async getDevProxyTasks(): Promise<vscode.Task[]> {
38+
const tasks: vscode.Task[] = [];
39+
40+
tasks.push(this.createStartTask());
41+
tasks.push(this.createStopTask());
42+
43+
return tasks;
44+
}
45+
46+
private createStartTask(): vscode.Task {
47+
const definition: DevProxyTaskDefinition = {
48+
type: 'devproxy',
49+
command: 'start',
50+
label: 'Start Dev Proxy'
51+
};
52+
53+
return this.createTaskFromDefinition(definition);
54+
}
55+
56+
private createStopTask(): vscode.Task {
57+
const definition: DevProxyTaskDefinition = {
58+
type: 'devproxy',
59+
command: 'stop',
60+
label: 'Stop Dev Proxy'
61+
};
62+
63+
return this.createTaskFromDefinition(definition);
64+
}
65+
66+
private createTaskFromDefinition(definition: DevProxyTaskDefinition): vscode.Task {
67+
let execution: vscode.ShellExecution;
68+
69+
if (definition.command === 'start') {
70+
const args = this.buildArgumentsFromDefinition(definition);
71+
execution = new vscode.ShellExecution(this.devProxyExe, args, {
72+
cwd: '${workspaceFolder}'
73+
});
74+
} else if (definition.command === 'stop') {
75+
// Use curl to stop Dev Proxy via API
76+
const configuration = vscode.workspace.getConfiguration('dev-proxy-toolkit');
77+
const apiPort = configuration.get('apiPort', 8897);
78+
execution = new vscode.ShellExecution('curl', [
79+
'-X', 'POST',
80+
`http://localhost:${apiPort}/proxy/stopproxy`
81+
]);
82+
} else {
83+
throw new Error(`Unsupported command: ${definition.command}`);
84+
}
85+
86+
const task = new vscode.Task(
87+
definition,
88+
vscode.TaskScope.Workspace,
89+
definition.label || `Dev Proxy: ${definition.command}`,
90+
DevProxyTaskProvider.DevProxyType,
91+
execution,
92+
definition.command === 'start' ? ['$devproxy-watch'] : []
93+
);
94+
95+
// Configure task properties based on command
96+
if (definition.command === 'start') {
97+
task.group = vscode.TaskGroup.Build;
98+
task.isBackground = true;
99+
task.presentationOptions = {
100+
echo: true,
101+
reveal: vscode.TaskRevealKind.Always,
102+
focus: false,
103+
panel: vscode.TaskPanelKind.Dedicated,
104+
showReuseMessage: true,
105+
clear: false
106+
};
107+
} else if (definition.command === 'stop') {
108+
task.group = vscode.TaskGroup.Build;
109+
task.presentationOptions = {
110+
echo: false,
111+
reveal: vscode.TaskRevealKind.Silent,
112+
focus: false
113+
};
114+
}
115+
116+
return task;
117+
}
118+
119+
private buildArgumentsFromDefinition(definition: DevProxyTaskDefinition): string[] {
120+
const args: string[] = [];
121+
122+
// Handle specific properties
123+
if (definition.configFile) {
124+
args.push('--config-file', definition.configFile);
125+
}
126+
127+
// Add any additional args
128+
if (definition.args) {
129+
args.push(...definition.args);
130+
}
131+
132+
return args;
133+
}
134+
}
135+
136+
export const registerTaskProvider = (context: vscode.ExtensionContext) => {
137+
const provider = new DevProxyTaskProvider(context);
138+
context.subscriptions.push(
139+
vscode.tasks.registerTaskProvider(DevProxyTaskProvider.DevProxyType, provider)
140+
);
141+
};

0 commit comments

Comments
 (0)