Commit Graph

60 Commits

Author SHA1 Message Date
root 300393dae1 fix(crop): initialize openPresetGroup state to null 2026-07-16 21:46:28 +08:00
root b363dcf888 feat(canvas): add leafer GPU renderer and interactive color-boundary crop tool
Introduce a leafer-ui canvas layer that mirrors rendered nodes and drives
viewport, node-drag, and alignment-guide updates imperatively, committing
React state on idle via startTransition to keep pan/zoom/drag at 60fps. Wire
the imperative viewport through wheel zoom, zoom-to, fit-view, and panning.

Add a dedicated crop tool: click a node to auto-detect a color-boundary crop
region or drag to preselect one, previewed with an on-canvas draft overlay
before entering the crop editor. Route uploads through renderContent so the
transparent WebP texture feeds the fast display path. Add node --test
coverage for the leafer renderer and color-boundary detection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 20:46:31 +08:00
root 8e1506e4c4 feat(canvas): produce and consume transparent renderContent textures
Rasterize imported SVG/CAD sources to a transparent WebP render texture and
carry it as an optional renderContent alongside the original content through
the domain node, snapshot normalization, and reference images. Add
canvasNodeRenderContent and prefer it for artboard, layer, generated-file,
and project thumbnail previews while keeping content as the crop/download/
model-reference source. Generalize the SVG rasterizer with a render purpose
and add upload/reference coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 20:46:12 +08:00
root ac6f1d84af feat(canvas): add CAD vector semantic context and non-destructive vector crop
Extend CAD conversion to emit bounded semantic metadata (units, layers,
blocks, entity types, labels, crop-indexed bounds) alongside the derived
SVG, tag imported drawings as cad-vector nodes, and carry semanticContext
through canvas nodes, snapshot normalization, and reference images. Agent
Chat forwards this metadata as hidden cad-context reference parts.

Add non-destructive vector cropping: cropping a vector/CAD node keeps the
source SVG and spawns a transparent WebP sibling with crop-scoped semantic
context, wired through the vectorized image toolbar and the workspace crop
tool. Include node --test coverage for CAD semantics and vector crop.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 16:42:30 +08:00
root 57a9aba03e refactor(canvas): install wheel zoom via a passive-safe native listener
Move canvas wheel zoom off the React onWheel prop into a manually attached
non-passive listener so preventDefault reliably suppresses page scroll, and
read the viewport from the ref to keep the handler referentially stable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 16:40:39 +08:00
root 078b0bee32 feat(canvas): import DWG/DXF CAD drawings as canvas assets
Accept DWG and DXF files (up to 24 MB) through the canvas asset picker and
drag-and-drop. Conversion runs locally in a browser worker via acad-ts,
uploads a sanitized derived SVG, and leaves the source file untouched. DXF
covers ASCII and binary drawings; DWG covers AutoCAD R14 through 2018.

Rename the image-only upload input/handler to a generic canvas asset flow,
add vector-image node detection, tag imported SVGs as vector-image nodes,
localize CAD import status/error messages, and switch the Next build to the
webpack compiler so the worker bundles correctly. Add a node --test suite
covering CAD conversion and vector image helpers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 12:09:05 +08:00
root 09b961fcc4 feat(canvas): attach uploaded image names to model prompts
Add modelImageReferences to preprocess agent contents, uploading local
image references and surfacing their names in the prompt so the model can
cite them. Wire the preparer into the canvas agent submission path, pass
imageName through the floating composer references, and relax the prompt
directive parser to accept names containing arbitrary characters.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 12:08:43 +08:00
root b86173b8a7 chore(frontend): shorten document title to "Moteva"
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 10:04:06 +08:00
root cc5753c19d style(ui): refine composer and image drop border radius and padding
Drive the drop-target border radius from --image-drop-radius, enlarge the
overlay radius, and widen the composer editor padding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 10:04:06 +08:00
root bb8946b79b feat(canvas): add visual annotation edit action
Add a VisualAnnotationPanel letting users mark regions on an image (brush,
circle, rectangle, cross) with per-mark edit instructions, composited into
an annotation guide image. The new "visual-annotation" node action sends
the unmarked source plus the annotated guide to the image model, editing
only numbered regions. Server validates the annotation image/instructions
and threads them through the generator task.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 10:03:59 +08:00
root 0ef4b7c1ee feat(ui): add drag-and-drop image upload to composers
Add an ImageDropOverlay component and useImageDropTarget hook that let
users drop an image onto the home prompt card or canvas agent composer to
upload it as a reference, with a localized drop overlay.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 01:02:12 +08:00
root 58f11302fe feat(auth): add device session tracking with configurable limits
Track authenticated sessions per device (parsing user-agent for desktop
vs mobile via mileusna/useragent), enforce configurable concurrent device
limits (Auth.DeviceLimits), and surface device status and "remove other
devices" management in the account dialog. Adds device/session context to
the auth module stores and exposes limits through the API.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 01:02:05 +08:00
root 875fff825c feat(canvas): add loading state for agent history retrieval 2026-07-10 23:09:42 +08:00
root 0363170eab change(ui): increase font size of disabled button from 13px to 14px 2026-07-10 23:06:38 +08:00
root 4f8c32b5ac change(ui): increase font size of disabled button from 12px to 14px 2026-07-10 23:05:00 +08:00
root b704335f6b change(ui): adjust font size of home prompt editor 2026-07-10 23:03:46 +08:00
root 0edff0e1cb refactor(ui): remove unused toolbar dot indicator
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 22:42:41 +08:00
root 6f998480bc feat(canvas): show loading state while agent history loads
Track agent history loading in the workspace and render a spinner with a
localized "loading conversation history" message in the assistant feed,
so the empty state no longer flashes before history resolves.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 22:42:41 +08:00
root 0a68551bfd change(ui): default composer image quality to medium
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 22:35:08 +08:00
root 0968f10f86 refactor(ui): simplify composer settings chip and animate chevron
Condense the settings-chip summary to quality, ratio, and image count
(dropping resolution and pixel size), wrap the label in an ellipsized
span, and swap the up/down chevron for a single rotating ChevronDown
across the canvas agent and image generator composers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 22:35:08 +08:00
root 71a1b3ace4 feat(frontend): add canvas agent empty state with server-driven starters
Render a CanvasAgentEmptyState in the Agent panel that fetches localized
starter content from the new agent-starters endpoint, with local defaults
as fallback. Clicking a starter focuses the prompt composer (new focus
handle). Includes accompanying UI polish: side-nav cleanup, animated
prompt examples, and canvas panel spacing tweaks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 22:19:22 +08:00
root 2df9ae6581 feat(frontend): add brand kit management UI and project binding
Add a brand kit domain model, repository, and dedicated page/route for
managing brand kits, plus a BrandKitSelector used on the home page and
canvas workspace. Home project creation and the workspace can attach a
brand kit to a project, with new i18n strings and a side-nav entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 20:59:05 +08:00
root 3653474355 refactor(ui): add size variants to Switch and consolidate styles
Introduce sm/md/lg sizes on the Switch component driven by CSS custom
properties, move switch styling into a dedicated switch.css, and remove
the duplicated overrides from styles.css and ToolbarCustomizeDialog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 20:58:45 +08:00
root d5f9cb366a refactor(infrastructure): modularize designGateway into focused modules
Split the monolithic designGateway.ts (1000+ lines) into organized modules:
- types.ts: type definitions and API contracts
- request.ts: HTTP request utilities
- responses.ts: response type definitions
- canvas.ts: canvas-related API calls
- projects.ts: project management operations
- agents.ts: agent/thread API operations
- generation.ts: image generation operations
- events.ts: event streaming and handlers
- canvasSnapshot.ts: snapshot management
- sharing.ts: share context and permissions
- assets.ts: asset operations
- clientIds.ts: client ID utilities
- shareContext.ts: share context helpers

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-10 16:58:21 +08:00
root 14eaece0ac feat(canvas): add shared workspace access and controls 2026-07-10 14:47:19 +08:00
root 60130b3d9b feat(canvas): build PSD export in the browser from canvas layers
Move PSD generation off the server. The image-generation API only
produces raster formats, so drop the PSD request path, the oov/psd
decoder, and the LayeredDocumentGenerator wiring. Layer separation now
returns clean background, foreground, and text_render_data artifacts
into a transparent frame.

Export that frame (or any image node) as PSD from the canvas context
menu: ag-psd assembles layers, rotation/flip, opacity, editable text,
and stroke effects from the current canvas state at download time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 11:01:46 +08:00
root 4ff246a294 feat(canvas): resolution/ratio composer settings and quality/count controls
Replace the ratio-baked size presets with a resolution tier (1K/2K/4K) plus
ratio selection and normalized dimensions, send imageQuality/imageCount to
the agent, and add the output_format field to GeneratorTaskInputArgs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 20:43:35 +08:00
root a1503a1687 feat(canvas): frame-based layer separation UI
Render and manage the separated layers produced by the edit-elements
action as a manual-frame container with attached image and text
children.

- canvasNodeOps: frame container/child helpers, render ordering,
  auto-attach nodes to containing frames, and layer reordering
- CanvasWorkspace wires frame-aware selection, drag, resize, hide/lock,
  and layer reorder through the new ops
- CanvasPanels: expandable layer tree with rename/reorder
- designGateway.submitGeneratorTask + GeneratorTaskSubmitResponse and
  bbox/generator_name artifact metadata in the domain
- ArtboardPreview shows a working state for generating frame layers
- i18n: expandLayer / renameLayer / layerTitlePlaceholder; styles

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 12:27:00 +08:00
root 676e1c4c67 fix(canvas): start selection title rename on single click
Switch the editable selection title from onDoubleClick to onClick so
renaming a node/layer title begins with a single click.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 12:26:26 +08:00
root 906846a717 style(ui): widen image generator model button to 180px
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 09:05:55 +08:00
root 4f2825bb8e feat(ui): localize friendly agent errors and surface them as toasts
Thread a translate function through friendlyAgentErrorMessage/
friendlyProjectFailureMessage and move the hard-coded zh-CN error copy
into the i18n locale files (with a zh-CN fallback map). Generation
stream failures now report through a toast via showGenerationError in
addition to setError, so the removed inline .panel-error footer is
gone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 09:05:44 +08:00
root 8a28a0bcea perf(canvas): slow generator task poll interval to 5s
Reduce polling pressure on the generator task status endpoint by raising
the client poll interval from 3s to 5s.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 02:20:33 +08:00
root 94718553c6 feat(ui): redesign image generator floating composer and settings panel
Compact the floating composer with an auto-resizing prompt editor and a
scrollable settings popover, add a titled settings panel, and show the
resolved image size in the settings summary. Add the imageCountLabel
string for the count section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:46:24 +08:00
root cbf4e21e2b feat(canvas): per-generator target size, placement and draft preservation
Persist each image-generator node's target resolution in metadata and
surface it in the selection frame and node preview. Place new generators
without overlapping existing ones, keep local draft generators when a
compressed snapshot omits them, and add a dedicated selection-frame
variant plus scale-aware preview styling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:46:16 +08:00
root 82683c40ea refactor(canvas): support multiple concurrent image generator streams
Track image-generator streams in a keyed Map/Set instead of a single ref
so several placeholders can generate at once without cancelling each
other. Generating state is derived from the number of open streams.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:46:07 +08:00
root 453de420fc fix(ui): show real contents in optimistic image messages and widen settings chip
Use the user-visible contents (without injected image-mode settings) for the
optimistic agent messages so the settings blob is not echoed in the thread.
Widen the composer settings chip to 150px so longer labels are not clipped.
Also picks up regenerated next-env.d.ts and tsbuildinfo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:10:17 +08:00
root a39e18950c refactor(auth): require bearer token only, drop legacy token header and cookie
Authenticate requests solely from the Authorization: Bearer header on the
server; stop accepting the legacy `token` header and `usertoken` cookie.
The frontend no longer sets auth cookies (only clears legacy ones), omits
credentials on all requests, and drops the redundant `token` header. Project
event SSE now streams over fetch so it can carry the Authorization header,
which EventSource cannot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:09:39 +08:00
root 263748af4a feat(api): add Lovart-style project and agent thread endpoints
Add canva/canda-compatible routes for lightweight project open/save and
agent thread history:
- POST /canva/project/queryProject, saveProject
- POST /canva/agent/queryAgentLastThread, agentThreadList
- GET /canda/chat-history, /canda/thread/status

Canvas save now accepts a compressed SHAKKERDATA:// snapshot payload,
preserves connections, and returns a SaveProject response; blank
successful image nodes are backfilled from generated artifacts. Frontend
designGateway adopts the new save/query flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 19:10:08 +08:00
root ada29cee12 refactor(agent): make emoji optional and sparse in agent replies
Loosen the creative agent guidance so emoji are used only as sparse
category markers rather than forced on every list item, and tighten the
frontend emoji section-break normalization to only split before short
labelled headings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 16:18:11 +08:00
root 0eed208bbf feat(ui): add typewriter effect for streaming agent text
Add a useTypewriterText hook that reveals streamed content character by
character and reconciles when the target text changes. Apply it to
markdown content and agent step copy, with a blinking caret while
streaming.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 15:08:21 +08:00
root d7300ed0f6 feat(ui): make workspace layout responsive for narrow and mobile screens
Widen the assistant panel via a shared CSS variable, overlay it below
1180px, and add mobile breakpoints for the topbar, canvas controls,
toolbar, minimap, and bottom-sheet assistant panel. Use dvh units and
safe-area insets for mobile viewports.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 14:39:00 +08:00
root b842c34fca feat(ui): add scroll-to-latest button in assistant feed
Track the assistant feed scroll position and footer height, and show a
floating button to jump back to the newest message when scrolled up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 14:33:02 +08:00
root e9cfadfb90 refactor(ui): extract NotFoundPage into its own i18n-aware module
Move the inline 404 component and its styles out of App.tsx into a
dedicated NotFoundPage module, and localize its copy via i18n keys.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:16:30 +08:00
root c73e51e400 feat(i18n): add not-found page copy keys
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:16:20 +08:00
root 4e98a81aae feat(ui): path-based app-router routes with 404 and project auth preview
Resolve routes from pathname (and legacy hash), add a notFound route with
a dedicated 404 page, and show a blurred workspace preview for
unauthenticated project visits. Wire up Next.js app-router entry files and
listen for popstate so history navigation updates the route.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:07:13 +08:00
root 92343ef1f6 feat(ui): surface friendly agent and project failure messages
Add friendlyAgentErrors to map raw agent/image errors to user-facing
copy, and use it for timeline error bubbles and project failure banners.
Redirect home with a toast when a project returns 403/404 instead of
showing a generic error, and render the final agent response inline under
skill progress.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:07:05 +08:00
root 1a1c0a6544 fix(image): add response-header timeout and idempotent retry
Give the image client a configurable ResponseHeaderTimeout (default 4m,
capped at the overall timeout) so a stalled upstream fails fast, and
retry such timeouts when an idempotency key is set so a slow-but-safe
request can recover instead of terminating. Raise the Next.js API proxy
maxDuration to 1200s to accommodate long generations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 10:56:42 +08:00
root 222e5a0219 refactor(ui): focus the product on image generation only
Drop the disabled video/3D model tabs from the composer and home model
picker, reword storyboard/campaign copy away from motion/video toward
static campaign frames, ease the home prompt editor font sizing, and
update the deterministic fallback message to describe image generation
and editing instead of "video not yet supported".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 10:56:14 +08:00
root d5c5470c3c feat(timeline): download generated images from a hover control
Render generated artifacts with a native <img> at their true aspect
ratio instead of a background-image fill, and add a hover/focus download
button that fetches the blob (falling back to a direct link) and saves
it with a sanitized, extension-aware filename.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 10:56:04 +08:00
root a549c7b14b refactor(i18n): extract inline dictionaries into locale JSON files
Move the large in-code zh-CN/en-US dictionaries out of i18n.tsx and
import them from locales/*.json, shrinking the module and making
translations easier to edit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 10:55:56 +08:00