Built-in design generation now runs as an agentic MCP tool-loop (reusing the agent-rs BuiltInProvider), gated behind OPENPENCIL_DESIGN_AGENT_LOOP / the Settings experimental toggle; the orchestrator stays the default. - design-agent system prompt + in-process design toolset (parity-locked with the MCP surface) + flag-gated Intent::Design routing - spawn_agents execution as sequential sub-loops + live creation-mode badges (per-agent glow + 'N/M designing...' header) - new MCP tools: get_guidelines, ToolSearch, get_screenshot, get_editor_state, export_nodes, spawn_agents; style-guide local audit - #27 AI panel restyle: rounded tool cards + green check-rings, gray user bubbles, model-pill bottom toolbar, header, empty-state pills, the PARALLEL AGENTS (agent_team_size) 1x-6x chip dropdown - multi-chat tabs: ChatSessions model (Deref-to-active) + tab row UI (switch / close / + / Cmd+T) with each run bound to its tab Large checkpoint commit spanning the working tree (Rust shell crates).
47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
// apps/web/server/api/mcp/screenshot.post.ts
|
|
import { defineEventHandler, readBody, createError } from 'h3';
|
|
import { sendToClient, getLastActiveClientId, isClientConnected } from '../../utils/mcp-sync-state';
|
|
import {
|
|
allocateRequestId,
|
|
registerPending,
|
|
type ScreenshotRequestBody,
|
|
} from '../../utils/mcp-screenshot-rpc';
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const body = (await readBody(event)) as ScreenshotRequestBody;
|
|
const timeoutMs = Math.min(body.timeoutMs ?? 15000, 60000);
|
|
|
|
// 1. Resolve target renderer — fail fast if none
|
|
const targetClientId = getLastActiveClientId();
|
|
if (!targetClientId || !isClientConnected(targetClientId)) {
|
|
throw createError({
|
|
statusCode: 503,
|
|
statusMessage:
|
|
'No active editor client — make sure an Electron window or /editor tab is open and focused.',
|
|
});
|
|
}
|
|
|
|
// 2. Allocate request id and try to send
|
|
const requestId = allocateRequestId();
|
|
const sent = sendToClient(targetClientId, {
|
|
type: 'screenshot:request',
|
|
requestId,
|
|
bounds: body.bounds,
|
|
nodeId: body.nodeId,
|
|
opts: body.opts,
|
|
timeoutMs,
|
|
});
|
|
|
|
// 3. Only register pending + start timeout AFTER successful send (Q3 decision)
|
|
if (!sent) {
|
|
throw createError({
|
|
statusCode: 503,
|
|
statusMessage:
|
|
'Failed to deliver screenshot request — target editor client disconnected between check and send.',
|
|
});
|
|
}
|
|
|
|
// 4. Await renderer response (or timeout)
|
|
return await registerPending(requestId, timeoutMs);
|
|
});
|