improved a lot of things
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
// Authentication: Bearer <workspace_token> (HMAC-SHA256, issued by issueWorkspaceToken).
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { verifyWorkspaceToken, TOOL_MAP } from '@originmain/agent-bridge';
|
||||
import { verifyWorkspaceToken, TOOL_MAP, getToolList } from '@originmain/agent-bridge';
|
||||
import type { JsonRpcRequest, ToolContext } from '@originmain/agent-bridge';
|
||||
import {
|
||||
getDiffsByStatus,
|
||||
@@ -47,12 +47,10 @@ export async function POST(req: NextRequest) {
|
||||
}
|
||||
|
||||
// tools/list — meta-endpoint; return available tools without executing one.
|
||||
// MCP spec requires each entry to include inputSchema so clients can
|
||||
// construct valid tool calls without out-of-band documentation.
|
||||
if (body.method === 'tools/list') {
|
||||
const tools = [...TOOL_MAP.values()].map(t => ({
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
}));
|
||||
return NextResponse.json({ jsonrpc: '2.0', id: body.id, result: { tools } });
|
||||
return NextResponse.json({ jsonrpc: '2.0', id: body.id, result: { tools: getToolList() } });
|
||||
}
|
||||
|
||||
// ── Dispatch ────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -17,7 +17,7 @@ export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const db = serverClient();
|
||||
const file = await getActiveDesignLanguageFile(db, workspaceId);
|
||||
if (!file) return NextResponse.json(null, { status: 204 });
|
||||
if (!file) return NextResponse.json(null);
|
||||
return NextResponse.json(file);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||
|
||||
@@ -55,8 +55,12 @@ export function Artboard({ id, label, x, y, width, height, renderUrl }: Artboard
|
||||
}, [localFiberRoot, selectComponent]);
|
||||
|
||||
// ── Drag to reposition ─────────────────────────────────────────────────────
|
||||
const isDragging = useRef(false);
|
||||
const dragStart = useRef({ mouseX: 0, mouseY: 0, artX: 0, artY: 0 });
|
||||
const isDragging = useRef(false);
|
||||
const dragStart = useRef({ mouseX: 0, mouseY: 0, artX: 0, artY: 0 });
|
||||
// dragOffsetRef carries the live offset into the onUp closure, avoiding the
|
||||
// stale-state problem that occurs when useCallback captures dragOffset before
|
||||
// any mousemove events have fired.
|
||||
const dragOffsetRef = useRef({ dx: 0, dy: 0 });
|
||||
const [dragOffset, setDragOffset] = useState({ dx: 0, dy: 0 });
|
||||
|
||||
const onLabelMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
@@ -65,6 +69,7 @@ export function Artboard({ id, label, x, y, width, height, renderUrl }: Artboard
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
isDragging.current = true;
|
||||
dragOffsetRef.current = { dx: 0, dy: 0 };
|
||||
const { zoom, panX, panY } = useViewport.getState();
|
||||
dragStart.current = {
|
||||
mouseX: (e.clientX - panX) / zoom,
|
||||
@@ -79,10 +84,13 @@ export function Artboard({ id, label, x, y, width, height, renderUrl }: Artboard
|
||||
const { zoom: z, panX: px, panY: py } = useViewport.getState();
|
||||
const curX = (mv.clientX - px) / z;
|
||||
const curY = (mv.clientY - py) / z;
|
||||
setDragOffset({
|
||||
const offset = {
|
||||
dx: curX - dragStart.current.mouseX,
|
||||
dy: curY - dragStart.current.mouseY,
|
||||
});
|
||||
};
|
||||
// Update the ref first so onUp always reads the final position.
|
||||
dragOffsetRef.current = offset;
|
||||
setDragOffset(offset);
|
||||
};
|
||||
|
||||
const onUp = () => {
|
||||
@@ -91,8 +99,10 @@ export function Artboard({ id, label, x, y, width, height, renderUrl }: Artboard
|
||||
window.removeEventListener('mousemove', onMove);
|
||||
window.removeEventListener('mouseup', onUp);
|
||||
|
||||
const newX = Math.round(dragStart.current.artX + dragOffset.dx);
|
||||
const newY = Math.round(dragStart.current.artY + dragOffset.dy);
|
||||
// Read the final offset from the ref — never stale regardless of when
|
||||
// useCallback last reconstructed onLabelMouseDown.
|
||||
const newX = Math.round(dragStart.current.artX + dragOffsetRef.current.dx);
|
||||
const newY = Math.round(dragStart.current.artY + dragOffsetRef.current.dy);
|
||||
|
||||
// Persist position
|
||||
fetch(`/api/artboards/${id}`, {
|
||||
@@ -104,12 +114,13 @@ export function Artboard({ id, label, x, y, width, height, renderUrl }: Artboard
|
||||
}).then(() => {
|
||||
queryClient.invalidateQueries({ queryKey: ['artboards', workspaceId, projectId ?? undefined] });
|
||||
setDragOffset({ dx: 0, dy: 0 });
|
||||
dragOffsetRef.current = { dx: 0, dy: 0 };
|
||||
}).catch(console.error);
|
||||
};
|
||||
|
||||
window.addEventListener('mousemove', onMove);
|
||||
window.addEventListener('mouseup', onUp);
|
||||
}, [id, x, y, width, height, renderUrl, workspaceId, projectId, queryClient, dragOffset.dx, dragOffset.dy]);
|
||||
}, [id, x, y, width, height, renderUrl, workspaceId, projectId, queryClient]);
|
||||
|
||||
// ── Inline rename ──────────────────────────────────────────────────────────
|
||||
const [renaming, setRenaming] = useState(false);
|
||||
|
||||
@@ -62,7 +62,7 @@ export function ProjectSettingsForm({
|
||||
memberRole,
|
||||
}: ProjectSettingsFormProps) {
|
||||
const router = useRouter();
|
||||
const isOwnerOrDev = memberRole === 'OWNER' || memberRole === 'DEVELOPER' || memberRole === 'DESIGNER';
|
||||
const isOwnerOrDev = memberRole === 'OWNER' || memberRole === 'ENGINEER' || memberRole === 'DESIGNER';
|
||||
|
||||
/* ── Form state ── */
|
||||
const [name, setName] = useState(initialName);
|
||||
@@ -229,7 +229,7 @@ export function ProjectSettingsForm({
|
||||
border: '1px solid rgba(239,68,68,0.35)', background: 'transparent',
|
||||
color: '#EF4444', cursor: deleteConfirm.trim() === initialName.trim() ? 'pointer' : 'not-allowed',
|
||||
flexShrink: 0,
|
||||
opacity: deleteConfirm.trim() !== name.trim() || deleting ? 0.4 : 1,
|
||||
opacity: deleteConfirm.trim() !== initialName.trim() || deleting ? 0.4 : 1,
|
||||
}}
|
||||
>
|
||||
{deleting ? 'Deleting…' : 'Delete project'}
|
||||
|
||||
Reference in New Issue
Block a user