docs: record CAD import and image-reference planning notes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-15 12:09:10 +08:00
parent 078b0bee32
commit f36222c6c6
3 changed files with 203 additions and 1 deletions
+66
View File
@@ -1,5 +1,16 @@
# Findings: Server-Backed Brand Kit Canvas Context # Findings: Server-Backed Brand Kit Canvas Context
## 2026-07-15 Vector Reference Follow-up
- Raw CAD/SVG reference text is caused by the prompt-directive parser stopping at the first closing parenthesis in filenames such as `...2026-05-05(1) (DXF).svg`; the existing capsule and hover-preview UI is already shared with WebP references.
- GPT Image rejects SVG input bytes even when the canvas and browser can render them. The SVG source must remain unchanged on canvas and be rasterized to alpha-preserving WebP only when building model-bound image contents.
- Browser rasterization is the appropriate conversion boundary because the generated CAD SVG relies on reusable definitions, `<use>`, patterns, text, and browser SVG rendering semantics.
- `CanvasWorkspace.generate` is the shared Agent Chat and image-generator submission boundary. It currently uses the same `AgentContent[]` for optimistic display and the socket request, so model URL normalization must produce a separate request copy while the visible message retains the original SVG URL/name.
- SVG detection cannot rely only on public URL suffixes because uploaded asset URLs may not preserve the source extension; the `AgentContent` image name and fetched response MIME/type must also participate.
- `PromptComposer.toAgentContents()` already preserves `imageName`; `ImageGeneratorFloatingComposer` currently drops it and must retain the reference name so extension detection and user-facing labels remain reliable.
- Home creation uses serialized prompt directives rather than `AgentContent[]`, so it requires the same reference normalization before serialization if SVG attachments can immediately trigger generation there.
- The requested canvas scope has two model-bound submission sources, Agent Chat and the floating image-generator composer; both converge on `CanvasWorkspace.generate`, so one adapter at that boundary covers them without touching canvas persistence.
- The existing timeline capsule already routes canvas asset URLs through SVG-safe thumbnail/preview URL helpers and provides its copy behavior; once the directive parser recognizes the full filename, no separate vector-specific UI is needed.
## Requirements ## Requirements
- The previous implementation is frontend-only and insufficient for durable user ownership. - The previous implementation is frontend-only and insufficient for durable user ownership.
- The canvas header needs a compact Brand Kit selector beside the project name. - The canvas header needs a compact Brand Kit selector beside the project name.
@@ -82,3 +93,58 @@
- Brush, circle, rectangle, and cross marks use normalized coordinates, so the on-canvas overlay, uploaded guide raster, structured action payload, and resized canvas view stay aligned. - Brush, circle, rectangle, and cross marks use normalized coordinates, so the on-canvas overlay, uploaded guide raster, structured action payload, and resized canvas view stay aligned.
- Generation remains blocked until every mark has a non-empty editable instruction, preventing unlabeled regions from reaching the image model. - Generation remains blocked until every mark has a non-empty editable instruction, preventing unlabeled regions from reaching the image model.
- Follow-up invariant: visual annotation never changes the source node. Submission creates a sibling copy to the source's right; generation state, failures, and the final image are isolated to that copy. - Follow-up invariant: visual annotation never changes the source node. Submission creates a sibling copy to the source's right; generation state, failures, and the final image are isolated to that copy.
## CAD Import Request (2026-07-15)
- The infinite canvas should accept DWG and DXF drawings and display them through a derived SVG or canvas-compatible representation.
- The existing import, upload, persistence, and rendering architecture must be traced before selecting a converter or API boundary.
- The frontend is React 19/Next 16/Vite and currently has no CAD-specific dependency; `lucide-react` is the existing icon source.
- The backend is a single go-zero REST service. Any new REST conversion boundary must be added to `server/img_infinite_canvas.api` before generation.
- The working tree already contains a user-owned change to `frontend/next-env.d.ts`; CAD work must not modify or revert it.
- Canvas image upload is centralized through `designGateway.uploadImage`, with drag/drop filtering in `ImageDropOverlay` and an upload command in `WorkspaceToolbar`.
- The canvas already supports SVG image URLs and exports vector/image nodes to SVG or raster, making SVG the natural render target for CAD conversion.
- Existing client image upload preprocessing intentionally preserves SVG, while server asset uploads are generic `fileName` plus `contentType` requests.
- Image nodes render regular image URLs, including SVG, and persist their URL plus world-space dimensions in the existing canvas snapshot; no new canvas node type is required.
- `uploadImagesToCanvas` already performs optimistic node creation, parallel upload, selection, save, and failure cleanup. CAD import should convert first, then feed derived SVG `File` objects into this path.
- The current file input and drag/drop gates are image-only, so both explicit selection and DataTransfer parsing need CAD-aware file recognition and copy.
- No DWG/DXF converter CLI is installed in the local environment (`dwg2svg`, `dwg2dxf`, `dxf2svg`, LibreDWG tools, and Inkscape are absent).
- `dxf-parser` is available from npm and can cover browser-side ASCII DXF parsing, but it does not parse binary DWG; DWG needs a real LibreDWG/ODA/cloud conversion boundary rather than treating the binary file as SVG.
- The server configuration pattern supports adding a configurable CAD converter, but a default that depends on a missing host executable would leave local DWG import nonfunctional.
- Browser-capable packages now exist for DWG: `dwgdxf` provides an MIT-licensed WASM DWG-to-DXF converter, while several LibreDWG viewer/parser packages are GPL/AGPL and unsuitable as a casual dependency in a potentially proprietary app.
- A clean client pipeline is feasible: convert DWG bytes to DXF in a worker/WASM path, parse DXF, serialize supported entities into a sanitized standalone SVG, then reuse the existing image upload and canvas rendering flow.
- The canvas file input lives inside the stage and currently accepts `image/*`; the drag helpers are local functions in `CanvasWorkspace/index.tsx`, so CAD recognition can be scoped to this workspace without changing Home's reference-image drop behavior.
- `@node-projects/acad-ts` 2.3.0 is the strongest single dependency: MIT licensed, TypeScript-native, reads ASCII/binary DXF and DWG AC1014 through AC1032, and includes an SVG writer. Its 6.4 MB unpacked size argues for dynamic import so ordinary canvas startup is unaffected.
- `dwgdxf` is smaller and MIT but would still require a second DXF parser and a custom SVG renderer. The single `acad-ts` document model should preserve more entity/layer/text behavior with less application code.
- `@node-projects/acad-ts` ships as dependency-free ESM with first-class type declarations; its compressed tarball is about 969 KB, making a lazy-loaded import acceptable for CAD-only use.
- The frontend has no existing unit-test runner. Verification must rely on focused converter fixtures/manual scripts plus the existing TypeScript, Next, and Vite production builds unless introducing a runner becomes necessary.
- The selected package contains pure ESM/browser-neutral code with no Node built-in imports detected. It exports `DwgReader`, `DxfReader`, `SvgWriter`, and SVG converter internals from the main entry.
- The package's reader API accepts raw `ArrayBuffer` for DWG and `Uint8Array` for DXF, which aligns directly with browser `File.arrayBuffer()`.
- Source inspection found suspicious/incomplete closing-tag logic in the packaged `SvgXmlWriter`; the advertised SVG writer must pass a real fixture test before it is trusted. If it fails, retain its CAD readers but implement a small application-owned SVG serializer over the parsed document.
- The runtime fixture confirmed the writer emits invalid `</>` closing tags and maps default CAD color to white. The readers remain usable, but raw writer output cannot be uploaded directly.
- The writer's entity geometry is still valuable if its deterministic closing placeholders can be repaired and the root transform/color normalized before DOM validation; this is materially smaller than reimplementing arcs, hatches, inserts, and text.
- `SvgXmlWriter` can write to an `ArrayBuffer` sink and expose its complete string via `getOutput()`, avoiding fixed output buffer sizing.
- Final architecture: run the pure TypeScript DWG/DXF readers and geometry writer in a module worker; repair the writer's deterministic close placeholders; validate/sanitize with browser XML APIs; move the Y-axis flip into a bounded group; map CAD index-7 white to dark ink; size the derived SVG for canvas display; upload only that SVG.
- CAD files will be accepted only by the canvas asset input/drop path. Home/reference/clipboard image behaviors remain image-only.
- The installed package exposes `SvgXmlWriter` directly, so conversion can capture the generated string without guessing an output-buffer size. Text, groups, hatches, and inserts all use the same anonymous closing placeholder, enabling deterministic stack-based repair before XML parsing.
- Normalization will allowlist generated SVG elements/attributes, remove CSS/external-resource attributes, keep CAD text upright inside a drawing-wide Y flip, remap context-dependent CAD white to dark ink, and enforce readable non-scaling strokes.
- The implementation passes strict TypeScript compilation and locale JSON parsing. The worker uses the library collection's declared `count` API and preserves the existing image-only clipboard/reference paths.
- The full frontend build passes. Vite emits CAD conversion as a separate 1.02 MB worker chunk (201 KB gzip), so normal canvas JavaScript does not absorb the parser cost.
- Local preview dependencies are already listening on frontend port 5173 and backend port 8888. Playwright CLI prerequisites are available.
- Next's production output also includes worker-related chunks plus a `.ts` media asset; real-browser testing must confirm Turbopack serves executable worker code instead of treating the TypeScript source as a passive URL asset.
- The process currently occupying port 5173 belongs to an unrelated Electron/Vite project, not this repository. This app needs an isolated preview port.
- The selected CAD library repository provides real ASCII/binary DXF and DWG fixtures across AC1014-AC1032, including `samples/svg/export_sample.dwg`, enabling format-level browser verification without fabricated test data.
- Inspection confirmed the Turbopack media asset is raw TypeScript with a bare package import, so it would fail as a browser worker. Next must use a worker-aware build mode or the conversion must move off-worker.
- Next 16 officially supports `--webpack` for both dev and build. After switching scripts, the full Next+Vite build passes and the raw `.ts` worker media asset is gone; webpack emits the CAD dependency as a separate ~828 KB JavaScript chunk instead.
- Real-browser import of the selected library's own 116 KB DXF fixture fails before SVG generation because the parsed document exposes no model-space block. This invalidates the assumption that advertised DXF support is production-ready.
- The user's real failing file is a 915,957-byte AutoCAD R11/R12 (AC1009) DXF. R12 support is therefore a hard compatibility requirement, not an optional legacy case.
- Node verification shows the larger AC1015 upstream DXF does contain 161 model-space entities, while the geolocation fixture legitimately contains zero. The first browser failure still needs separation from the empty-fixture result before replacing all parsing.
- The exact R12 file parses successfully into 15 model-space entities referencing eight blocks and 11,205 nested drawing entities. The failure occurs later in `SvgXmlWriter`: its point/text/fill paths read raw ByLayer color index 256, whose RGB lookup is undefined, instead of using the resolved layer color.
- Resolving inherited entity colors before SVG serialization removes that library failure without changing the source file. The exact drawing now converts in about 0.6 seconds to a 2.24 MB SVG containing 10,518 points, 565 text elements, 114 polylines, and eight lines.
- Browser verification against the exact WeChat DXF completed the derived-SVG upload and project save with HTTP 200 responses, displayed nonblank paper-pattern geometry, emitted no console errors, and preserved the CAD node after reload.
- Next's production minifier renames `acad-ts` constructors, but the library uses `constructor.name` as its DXF metadata key; without repair, the parsed entities keep zero-valued geometry. The worker now restores stable names from the package's export keys before parsing, preserving normal production minification.
- The normally minified Next production build now imports the exact R12 DXF and the upstream `export_sample.dwg` fixture successfully; both produce persisted SVG image nodes without console errors.
- The second user-provided file, `/Users/liangxu/Desktop/花语江南6-204方案.dwg`, is an AutoCAD 2007/2008/2009 drawing with 4,376 model-space entities, 362 blocks, and 15,729 block entities. Parsing takes roughly 9-13 seconds, but the third-party SVG writer takes about 35 seconds and emits roughly 50 MB.
- Profiling at low arc tessellation shows recursive `INSERT` expansion contributes about 37.6 MB, while hatches contribute about 4 MB and all other model-space entity types about 1.3 MB. Increasing the timeout or reducing arc points would not address the dominant cost.
- `SvgXmlWriter._writeInsert` expands the referenced block at every occurrence and merges translation only, dropping scale and rotation. A generic fix must own reference assembly: serialize each block once, emit `<use>` instances with complete matrices, support MINSERT row/column instances, and guard nested reference cycles.
- The existing `VectorizedImageToolbar` already matches the requested compact `矢量` plus download UI. Its caller only identifies `layerRole === "vectorized-image"`, so normal uploaded SVGs and CAD-derived SVGs incorrectly receive the raster `image-node-toolbar`.
- SVG export already preserves SVG-backed source content through `downloadSvgSource`; vector detection can route the toolbar without changing the download implementation.
- Browser inspection of the second DWG reproduced the tiny-content symptom after the performance fix. Its extreme bounds come from one `MTEXT` entity around 550,000 drawing units away from the actual plans; the source marks that entity `isInvisible`, but the third-party SVG writer ignores CAD visibility. Excluding invisible/off/frozen-layer entities from both SVG output and bounds is the generic display fix.
+66
View File
@@ -1,5 +1,20 @@
# Progress Log # Progress Log
## Session: 2026-07-15 (Vector Reference Follow-up)
### Phases 21-22
- Restored the existing CAD work and regression context after session handoff.
- Confirmed the two independent failures: nested-parenthesis directives bypass the capsule parser, and SVG bytes reach a raster-only image-generation API.
- Locked the product boundary: SVG remains the canvas source; only model-bound references become temporary transparent WebP assets.
- Ran the focused frontend suite and reproduced both English and Chinese nested-parenthesis directives as deterministic failures; the raster WebP baseline still passes.
- Fixed nested-parenthesis directive parsing; all English, Chinese, and existing raster capsule parser cases pass.
- Added browser-side SVG detection by name, URL, response MIME, and content sniffing; model-bound SVG references render to a transparent 2048px WebP derivative, upload once, and cache by source URL.
- Wired both Agent Chat and the canvas image-generator composer through the shared submission adapter while retaining original SVG canvas content and display names.
- The 14-test frontend suite, TypeScript build, and diff whitespace checks pass.
- In-app browser initialization succeeded but no browser backend is currently available, so capsule hover and live request inspection remain unavailable in this environment.
- Production Next/Vite builds pass, the exact nested CAD filename regression passes, and the active Vite preview remains available at `http://127.0.0.1:5174`.
- Restored the pre-existing `frontend/next-env.d.ts` development route import after Next rewrote it during the production build.
## Session: 2026-07-10 ## Session: 2026-07-10
### Phase 1: Architecture Discovery ### Phase 1: Architecture Discovery
@@ -87,3 +102,54 @@
- Added backend validation, prompt constraints, clean-source plus guide-image inputs, action lifecycle copy, generator metadata, and focused action coverage. - Added backend validation, prompt constraints, clean-source plus guide-image inputs, action lifecycle copy, generator metadata, and focused action coverage.
- Targeted Go tests, locale JSON parsing, and frontend TypeScript validation pass. - Targeted Go tests, locale JSON parsing, and frontend TypeScript validation pass.
- Updated the action contract so visual annotation preserves the original and generates into a sibling copy placed to its right. - Updated the action contract so visual annotation preserves the original and generates into a sibling copy placed to its right.
## Session: 2026-07-15
### Phase 15: CAD Import Discovery and Design
- **Status:** in_progress
- Loaded the repository go-zero instructions plus the applicable Go, frontend, and file-planning skills.
- Preserved the pre-existing `frontend/next-env.d.ts` change and added the DWG/DXF request as a new plan phase.
- Completed the required workflow/skill reads and confirmed the frontend/backend toolchains and API-first constraint.
- Located the canvas upload/drop surfaces, generic asset upload API, existing SVG render/export support, and canvas node model.
- Traced the exact optimistic upload/save flow and confirmed converted CAD can reuse image-node rendering without changing persistence schemas.
- Confirmed no local CAD converter binary is available and began evaluating a browser-capable dependency that genuinely handles both DXF and DWG.
- Found an MIT-licensed client-side DWG-to-DXF WASM option and isolated the canvas-only import points that need extension.
- Compared candidate packages and selected `@node-projects/acad-ts` for a single browser-side DWG/DXF-to-SVG pipeline, pending package-level verification.
- Downloaded the exact package tarball for API/runtime inspection without changing repository dependencies yet.
- First package source inspection raced extraction in a parallel tool call; no repository files were affected, and inspection will continue from the actual extracted path.
- Verified the extracted package layout and confirmed the required reader/writer exports are browser-neutral.
- Inspected reader and SVG writer internals; scheduled a runtime fixture because the packaged XML closing logic appears incomplete.
- Ran a real DXF line/circle fixture: parsing succeeds, while raw SVG is invalid exactly as suspected. Conversion will include explicit normalization and validation around the third-party writer.
- Completed CAD import discovery and selected a worker-based, frontend-only conversion design with no REST contract changes.
- The first dependency install was blocked by parent-workspace discovery (`workspace:*`); no implementation files were changed by the failed command.
- Installed `@node-projects/acad-ts@2.3.0` with the repository's pnpm toolchain; package manifest and lockfile are now updated.
- Added the worker converter, SVG repair/sanitization, CAD-aware picker/drop flow, localized statuses, toolbar semantics, and README documentation. Initial typecheck found one third-party collection API mismatch.
- Corrected the collection API mismatch; `pnpm exec tsc -b`, locale JSON parsing, and `git diff --check` now pass.
- `pnpm build` passes for Next and Vite; Vite produced an isolated CAD worker chunk. Began real-browser verification against the already-running local stack.
- Confirmed backend 8888 is this project but frontend 5173 is unrelated; will launch this frontend on 5174 and use upstream CAD fixtures for DXF/DWG tests.
- Found a Next/Turbopack worker packaging defect before runtime release; the fix is to use Next's supported webpack mode for dev/build while keeping the existing isolated worker architecture.
- Updated Next dev/build scripts to webpack mode and reran `pnpm build` successfully; both Next and Vite now produce executable isolated worker chunks.
- Authenticated in a real browser, created a blank project, confirmed the CAD-aware toolbar control, and triggered a real AC1015 DXF import. Added a visible error toast because conversion failures were otherwise hidden in the canvas state.
- Reproduced the user-visible failure with an upstream DXF fixture and captured the exact cause: the third-party parser returned no model-space entities. Converter dependency/path replacement is now required.
- Received and identified the user's actual failing DXF as R11/R12 AC1009; switched verification to that exact file and stopped two stalled directory-list commands without touching the file.
- Reproduced the exact failure in Node and reduced it to a minimal R12 DXF: `SvgXmlWriter` crashes when POINT/TEXT fill colors use inherited ByLayer index 256.
- Extracted the worker's conversion core, resolved non-renderable inherited CAD colors before serialization, and added a Node regression test covering R12 point/text entities.
- Imported the exact 915,957-byte user file through the Vite production worker, confirmed upload/save success, visually checked the rendered paper patterns, and confirmed reload persistence with no browser console errors.
- Reproduced a Next-production-only zero-bounds result caused by class-name mangling in the CAD library's metadata lookup; restored exported constructor names inside the worker and added the mangled-name case to the regression test.
- Verified the regular minified Next production build with both the exact R12 DXF and a real DWG fixture; both upload and render successfully without globally disabling minification.
### Phase 18: General CAD Compatibility Follow-up
- **Status:** in_progress
- Reproduced the second user-provided DWG conversion outside the UI: parsing succeeds, but recursive block expansion produces a roughly 50 MB SVG and reaches the browser timeout boundary.
- Profiled model-space entity contributions and isolated repeated `INSERT` serialization as the dominant time and output-size cost.
- Confirmed the third-party insert path also ignores rotation and scale, making reusable block references a correctness fix as well as a performance fix.
- Located the existing compact vector toolbar and confirmed SVG export already downloads the original SVG source.
- Reduced the second DWG conversion from roughly 44 seconds/50 MB to about 9.6 seconds/8.5 MB by emitting 196 reachable block definitions once and 748 transformed references.
- Imported the optimized DWG in the browser and reproduced the remaining tiny-content framing problem; traced the false extents to a source entity explicitly marked invisible.
- Excluded invisible, off-layer, and frozen-layer entities from output and bounds. Reimport now produces a correctly framed 1200 x 839 vector node instead of 4074 x 1005 with large blank extents.
- Confirmed uploaded SVG/CAD nodes show only the compact `矢量` toolbar and download action; corrected the source-SVG filename so downloads do not gain a duplicate `.svg` suffix.
- Added focused regression coverage for inherited R12 colors, reusable repeated inserts, full insert transforms, MINSERT arrays, cyclic blocks, invisible extents, and SVG vector-node detection; all seven tests pass.
- Rechecked the exact R12 DXF after the assembler change: conversion completes in about 0.3 seconds and emits a 2.14 MB reusable SVG.
- Rechecked `/Users/liangxu/Desktop/花语江南6-204方案.dwg`: conversion completes in about 10 seconds, emits an 8.49 MB SVG instead of roughly 50 MB, and frames the visible drawing at a 1.43:1 aspect ratio.
- Browser import, nonblank rendering, compact vector toolbar, source SVG download, save, and reload persistence all pass at `http://127.0.0.1:5174`.
- Final `pnpm test`, TypeScript validation, `pnpm build`, and `git diff --check` pass; the build retains only the repository's existing Vite large-chunk warning.
+71 -1
View File
@@ -4,7 +4,7 @@
Persist Brand Kits by authenticated user, bind one optional Brand Kit to each project/canvas, expose a canvas-header selector, and make every Agent Chat turn and newly created thread use the selected kit as authoritative creative context. Persist Brand Kits by authenticated user, bind one optional Brand Kit to each project/canvas, expose a canvas-header selector, and make every Agent Chat turn and newly created thread use the selected kit as authoritative creative context.
## Current Phase ## Current Phase
Phase 12 Phases 21-22
## Phases ## Phases
@@ -91,6 +91,54 @@ Phase 12
- [ ] Provide the working preview URL and concise implementation notes - [ ] Provide the working preview URL and concise implementation notes
- **Status:** pending - **Status:** pending
### Phase 15: CAD Import Discovery and Design
- [x] Trace the canvas asset import, upload, persistence, rendering, and export paths
- [x] Define the supported DWG/DXF conversion boundary and failure states
- **Status:** complete
### Phase 16: CAD Import Implementation
- [x] Confirm no backend API change is required for browser-side conversion
- [x] Add DWG/DXF selection, conversion, SVG/canvas rendering, and user feedback
- [x] Add focused tests and documentation
- **Status:** complete
### Phase 17: CAD Import Verification and Delivery
- [x] Run relevant frontend tests/builds
- [x] Inspect CAD import and canvas behavior in a browser with the exact R12 file
- [x] Review scope and deliver concise support/limitation notes
- **Status:** complete
### Phase 18: General CAD Compatibility Follow-up
- [x] Reproduce the block-heavy DWG timeout and isolate its dominant output path
- [x] Replace recursive INSERT/DIMENSION expansion with reusable SVG block definitions and full insert transforms
- [x] Cover nested blocks, repeated inserts, MINSERT arrays, malformed references, and recursion cycles
- **Status:** complete
### Phase 19: Vector Image Toolbar Follow-up
- [x] Recognize uploaded SVG and CAD-derived SVG nodes as vector images
- [x] Hide the raster image toolbar and show the compact vector/download toolbar for vector nodes
- [x] Preserve original SVG download behavior
- **Status:** complete
### Phase 20: Follow-up Verification and Delivery
- [x] Verify both user-provided CAD files plus representative DWG/DXF regression fixtures
- [x] Run focused tests, typecheck, and production builds
- [x] Verify vector toolbar, rendering, download, and persistence in a real browser
- **Status:** complete
### Phase 21: Vector Reference Message Rendering
- [x] Reproduce CAD-derived SVG references falling back to raw prompt directives
- [x] Parse SVG/CAD reference names with nested parentheses into the existing message capsule
- [x] Verify SVG directives enter the existing thumbnail/hover/copy component path; run tests and production build
- **Status:** complete
### Phase 22: Model-Compatible SVG References
- [x] Identify every canvas frontend submission path that can pass an SVG image reference to image generation
- [x] Rasterize SVG references to transparent WebP only at the model submission boundary
- [x] Cache and replace submitted reference URLs without mutating SVG canvas nodes or display names
- [x] Add focused regression coverage and verify prepared model content receives a WebP asset URL
- **Status:** complete
## Invariants ## Invariants
- Brand Kits are owned and queried only through the authenticated user ID from request context. - Brand Kits are owned and queried only through the authenticated user ID from request context.
- A project may reference zero or one Brand Kit owned by the same user. - A project may reference zero or one Brand Kit owned by the same user.
@@ -107,6 +155,11 @@ Phase 12
- Device timestamps cross the API boundary as RFC3339 UTC instants and are localized only in the browser's timezone. - Device timestamps cross the API boundary as RFC3339 UTC instants and are localized only in the browser's timezone.
- Visual annotation actions never mutate the source image node; their copied result node is the only generation target. - Visual annotation actions never mutate the source image node; their copied result node is the only generation target.
- Desktop and mobile web-session limits come from server configuration; the API returns the effective values and the UI never hard-codes them. - Desktop and mobile web-session limits come from server configuration; the API returns the effective values and the UI never hard-codes them.
- Imported CAD files are read without mutation; only a sanitized derived SVG is uploaded and rendered, with explicit size, timeout, empty-drawing, and conversion errors.
- Repeated and nested CAD block references are represented once and instanced with SVG references; conversion cost must scale with unique block geometry, not insert count.
- SVG-backed image nodes use vector-only actions and download their source SVG rather than exposing raster editing actions.
- User-message image directives render through one attachment capsule/preview path regardless of raster or SVG source format.
- SVG remains the persisted canvas source; transparent WebP derivatives exist only for model-compatible image inputs.
## Errors Encountered ## Errors Encountered
| Error | Attempt | Resolution | | Error | Attempt | Resolution |
@@ -127,3 +180,20 @@ Phase 12
| Escaping the `psql \d` meta-command through Docker produced an invalid command | 1 | Query `information_schema.columns` and `pg_indexes` with regular SQL instead. | | Escaping the `psql \d` meta-command through Docker produced an invalid command | 1 | Query `information_schema.columns` and `pg_indexes` with regular SQL instead. |
| Desktop limit regression test observed two valid desktop sessions when the configured limit was 1 | 1 | Confirmed the limit was presentation-only; enforce it atomically during session creation and reconcile pre-fix sessions during device listing. | | Desktop limit regression test observed two valid desktop sessions when the configured limit was 1 | 1 | Confirmed the limit was presentation-only; enforce it atomically during session creation and reconcile pre-fix sessions during device listing. |
| Launching `mcp-zero` from `server/` used a repository-root relative path | 1 | Relaunch with `../.tools/bin/mcp-zero` while keeping generation output rooted in `server/`. | | Launching `mcp-zero` from `server/` used a repository-root relative path | 1 | Relaunch with `../.tools/bin/mcp-zero` while keeping generation output rooted in `server/`. |
| NPM lookup for a nonexistent `@loaders.gl/dxf` package returned 404 and stopped the chained lookup | 1 | Use independent package searches and validate the chosen converter package before installation. |
| Package inspection commands raced the tar extraction and looked under the wrong transient path | 1 | Inspect the extracted tree first, then run dependent file reads sequentially against the discovered path. |
| `npm install` inherited a parent workspace containing an unsupported `workspace:*` URL | 1 | Inspect local package-manager metadata and run installation with workspace discovery disabled or use the repository's actual package manager. |
| TypeScript rejected `.length` on the CAD library's entity collection | 1 | Use the collection's declared count/iteration API instead of assuming it is an array. |
| Next 16 Turbopack emitted the module worker as raw `.ts` instead of executable bundled JavaScript | 1 | Run Next dev/build through its supported webpack mode, which handles `new Worker(new URL(...))`; retain Vite's native worker bundling. |
| Used nonexistent Playwright CLI command `network` | 1 | Use the CLI's documented `requests` and `response-body` commands for network inspection. |
| First Vite DXF upload triggered dependency pre-bundling and a development-page reload | 1 | Retry after Vite finishes one-time dependency optimization; production worker output is already bundled. |
| Real upstream DXF fixture parsed to an empty model space in `@node-projects/acad-ts` | 1 | Validate the library's document assembly in Node, then replace the DXF path or reader entirely if real fixtures remain empty. |
| Directory-wide listing of the WeChat file folder stalled on container-managed storage | 1 | Use the exact user-provided path directly; metadata access confirms the file is readable. |
| The exact R12 DXF crashed while serializing the first inherited-color POINT | 1 | Resolve non-renderable ByLayer/ByBlock colors through the entity and layer before calling the third-party SVG writer; lock the case with a minimal R12 regression test. |
| Next production minification reduced valid DXF geometry to zero-valued entities | 1 | Restore `acad-ts` constructor names from stable export keys before its name-based metadata lookup; keep the normal minified build and cover the mangled-name path in the regression test. |
| Reusing one entity writer and slicing its cumulative string exhausted the Node heap on the exact R12 drawing | 1 | Give each entity a short-lived fragment writer so output assembly stays linear in total geometry size. |
| Node's strip-only TypeScript test runner rejected constructor parameter properties | 1 | Use explicit class fields and constructor assignments, which preserve the project test runner's supported syntax subset. |
| Vector reference regression suite failed on nested English and Chinese CAD filenames | 1 | Expected red phase confirmed: the directive regex stops before the final filename parenthesis; update it to bind the closing delimiter adjacent to the URL separator. |
| First post-fix parser assertion still expected no `index` property | 1 | The production parser correctly emits `index: undefined`; align the regression fixture with the stable result shape. |
| In-app browser discovery returned no available browser backend | 1 | Followed the browser skill troubleshooting flow and confirmed an empty backend list; retain automated tests/builds and report the interactive verification gap. |
| Combined final planning patch targeted progress lines as task-plan context | 1 | Split the update by file and apply each change against its exact current section. |