The Pluto server can now be run as a VSCode task, providing better integration with the VSCode UI and terminal management.
- Server runs in a dedicated VSCode terminal panel
- Full terminal UI with colors, formatting, and interactions
- Visible in the "Terminal" dropdown
- Can be brought to front or hidden as needed
- Appears in VSCode's task list
- Can be stopped/restarted via Command Palette
- Task lifecycle managed by VSCode
- Consistent with other VSCode tasks (build, test, etc.)
- Users can see server output in real-time
- Can interact with server output (copy, search, etc.)
- Automatic cleanup when VSCode closes
- Persistent across window reloads (if configured)
- Follows VSCode extension best practices
- Similar to Jest extension, Python debugger, etc.
- Users familiar with VSCode tasks know how to interact with it
New class in src/plutoServerTask.ts that manages the server as a VSCode task:
export class PlutoServerTaskManager {
async start(): Promise<void>; // Start server as task
async stop(): Promise<void>; // Stop server task
isRunning(): boolean; // Check if task is running
getServerUrl(): string; // Get server URL
waitForReady(): Promise<void>; // Wait for server to be ready
}PlutoManager now supports two modes:
-
Task Mode (default, recommended):
const manager = new PlutoManager(port, outputChannel, serverUrl, true);
-
Spawn Mode (legacy, for compatibility):
const manager = new PlutoManager(port, outputChannel, serverUrl, false);
The mode is controlled by the useTasksForServer parameter (defaults to true).
{
type: "pluto-server",
port: 1234
}- Reveal: Always (shows terminal when task starts)
- Panel: Dedicated (uses dedicated terminal panel)
- Focus: False (doesn't steal focus)
- Clear: False (preserves previous output)
- Show Reuse Message: False (cleaner UI)
The task is configured as a background task (isBackground: true), meaning:
- Doesn't block other tasks
- Runs continuously
- Only stops when explicitly terminated
When you open a Pluto notebook or run Pluto: Start Server:
- VSCode creates a new task
- Terminal panel opens (or switches to existing panel)
- Julia command executes:
julia -e "using Pluto; Pluto.run(...)" - Server output appears in real-time
- After ~5 seconds, server is considered ready
- Terminal Panel: Click "Terminal" → Find "Pluto Server (port 1234)"
- Task List: Command Palette → "Tasks: Show Running Tasks"
- Output: Server logs appear in real-time with colors and formatting
Three ways to stop:
- Command Palette:
Pluto: Stop Server - Task Menu: Tasks → Terminate Task → Pluto Server
- Terminal: Click trash icon on terminal panel
Uses HTTP polling to detect when server is ready:
- Task starts with Julia command
- Extension polls
http://localhost:1234every 1 second - When server responds (any response, even error), it's considered ready
- Maximum wait time: 60 seconds
- If server doesn't respond in time, task is terminated and error is thrown
Why HTTP Polling?
- More reliable than arbitrary timeout
- Works regardless of terminal output format
- Detects actual server availability (not just process start)
- VSCode tasks don't expose terminal output directly
Alternative approaches considered:
- Parse Terminal Output: VSCode doesn't provide API to read task terminal output
- Custom Pseudoterminal: Would require reimplementing task system
- Problem Matchers: Only work for error detection, not ready state
const julia = spawn("julia", ["-e", "using Pluto; Pluto.run(...)"]);
julia.stdout?.on("data", (data) => {
outputChannel.appendLine(data.toString());
});
julia.stderr?.on("data", (data) => {
outputChannel.appendLine(data.toString());
});Pros:
- Direct control over process
- Can easily parse stdout/stderr
- Lower level, more flexible
Cons:
- Output hidden in Output Channel
- No integrated terminal UI
- User can't interact with output
- Not visible in task list
- Requires manual cleanup
const task = new vscode.Task(
{ type: "pluto-server" },
vscode.TaskScope.Workspace,
"Pluto Server",
"pluto-notebook",
new vscode.ShellExecution("julia", [...])
);
task.presentationOptions = { reveal: vscode.TaskRevealKind.Always };
await vscode.tasks.executeTask(task);Pros:
- Integrated terminal UI
- User can see and interact with output
- Visible in task list
- Standard VSCode pattern
- Automatic cleanup
- Better UX
Cons:
- Harder to parse output
- Less direct control
- Requires VSCode task API knowledge
To switch back to spawn mode (not recommended):
// In extension.ts
const plutoManager = getSharedPlutoManager(
plutoPort,
{ ... },
serverUrl || undefined,
false // Use spawn instead of tasks
);Could add to package.json:
{
"pluto-notebook.useTasksForServer": {
"type": "boolean",
"default": true,
"description": "Use VSCode tasks for Pluto server (recommended) instead of child process"
}
}To test the task-based server:
- Press
F5to launch Extension Development Host - Open a Pluto notebook (
.pluto.jlfile) - Server starts automatically
- Check "Terminal" panel - you should see "Pluto Server (port 1234)"
- Terminal shows colored Julia output
- Try stopping/restarting server via Command Palette
- Ready Detection: Currently uses 5-second timeout (could be improved)
- Output Parsing: Can't easily detect specific server messages
- Task Cleanup: Relies on VSCode to clean up terminated tasks
- Better Ready Detection: Parse terminal output for "Go to" message
- Task Problem Matchers: Add problem matchers for Julia errors
- Multiple Servers: Support running multiple servers on different ports
- Task Provider: Register a custom task provider for better integration
- Terminal Link Provider: Make URLs in terminal clickable