diff --git a/findings.md b/findings.md index f01e41c..87382c2 100644 --- a/findings.md +++ b/findings.md @@ -253,3 +253,11 @@ - A drag bypasses color analysis and maps the pointer rectangle directly into normalized source coordinates, clamped to the same visible-region maximum. This remains correct under canvas pan and zoom because mapping uses current screen bounds. - Color analysis is capped at a 640-pixel edge and measured about 22ms for a fully connected 640 x 480 image in the local Node benchmark. - CAD/SVG source and semantic metadata are untouched: the preview texture is used only for click analysis, while the established source-based crop path creates the final result and crop-specific CAD context. + +## Reference-Anchored Generation Placement (2026-07-16) +- Canvas-backed composer references carry an ordered `canvas-node:` identity in `UploadedReferenceImage.id`, but `AgentContent` serialization keeps only the image URL/name and semantic context. +- Agent generation project updates currently enter through `useGenerationStream.applyProject` without any turn-specific placement hint, so generated nodes retain backend/default coordinates unrelated to the visible capsules. +- The placement rule must bind to the submitted turn, not the current composer state after reset: capture the last ordered canvas-backed reference at submit time and consume that anchor while reconciling newly introduced generated image nodes. +- A hidden `settings` directive now carries only the resolved node ID with the submitted turn; optimistic chat continues to render the original visible contents, so users do not see placement metadata. +- Resolution walks submitted capsules from right to left, preferring the stable `canvas-node:` identity and falling back to source URL matching. An unmatched external capsule falls back to the preceding canvas-backed capsule; no match emits no directive and preserves default placement. +- Backend placement applies to initial placeholders, non-incremental results, and every incremental result. Multiple outputs form a left-to-right row beside the anchor while the referenced image remains unchanged. diff --git a/progress.md b/progress.md index a9638cd..09ca215 100644 --- a/progress.md +++ b/progress.md @@ -198,6 +198,16 @@ - Benchmarked the maximum fully connected 640 x 480 color analysis at about 22ms and confirmed the updated single preview server responds at `http://127.0.0.1:5175`. - The configured in-app browser backend remained unavailable, so final interactive visual inspection is left to the running local preview; source-level interaction coverage and HTTP verification pass. +### Phase 34: Reference-Anchored Generation Placement +- **Status:** complete +- Started tracing ordered image capsules through prompt serialization, agent submission, streamed project updates, and generated-node reconciliation. +- Confirmed the capsule retains its canvas node ID before submission, while the current generation update path has no reference anchor for result placement. +- Added ordered canvas-reference resolution and a hidden per-turn anchor directive; the visible optimistic Agent message still contains only the user's original capsules and prompt. +- Positioned generation placeholders plus final incremental/non-incremental outputs to the right of the last canvas-backed capsule, with multiple outputs ordered horizontally and no-match behavior unchanged. +- Added frontend and Go regressions for last-capsule selection, URL fallback, unmatched external capsules, directive parsing, immutable anchors, multi-output ordering, and default placement. +- Verification passes: 36 frontend tests, strict TypeScript compilation, Next/Vite production builds, `go mod tidy`, full Go tests, Go build, focused final regressions, and `git diff --check`. +- Restarted the updated preview at `http://127.0.0.1:5175` with the rebuilt backend on `http://127.0.0.1:8889`; frontend, backend auth options, and the frontend API proxy all return HTTP 200. + ### Phase 30: Native-Resolution Vector Crop Fidelity - **Status:** in_progress - Reproduced the user-visible symptom from the supplied comparison: the cropped transparent WebP has substantially thicker CAD strokes and degraded text/detail than the source SVG. diff --git a/task_plan.md b/task_plan.md index 16cf925..cfe3891 100644 --- a/task_plan.md +++ b/task_plan.md @@ -213,6 +213,14 @@ Phase 32 - [x] Add focused regression coverage and run frontend verification - **Status:** complete +### Phase 34: Reference-Anchored Generation Placement +- [x] Preserve ordered canvas-node identity from submitted image capsules for the active agent turn +- [x] Place newly generated image nodes beside the last canvas-backed image capsule +- [x] Keep backend/default placement when no submitted capsule maps to a canvas node +- [x] Add multiple-capsule and fallback regression coverage +- [x] Run frontend tests, typecheck, build, and preview verification +- **Status:** complete + ## Invariants - 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. @@ -297,3 +305,6 @@ Phase 32 | Playwright request context bypassed the page's mocked asset route and could not resolve `asset.local` | 1 | Fetch the captured normalized SVG inside the page context so the route handler supplies the bytes. | | Combined performance findings patch matched entries in a different order than the current file | 1 | Re-read the exact section and apply the package/result additions against their real positions. | | Direct CDN import used LeaferJS's package ESM build, whose bare `@leafer/core` specifier is not browser-resolvable | 1 | Load the official prebundled browser distribution for the throwaway benchmark. | +| TypeScript widened the hidden reference-anchor content discriminator to `string` | 1 | Declare the helper's `AgentContent[]` return type explicitly and rerun the focused test and typecheck. | +| Detached `nohup` preview processes were reclaimed by the terminal runner | 1 | Start the frontend and backend in persistent tool sessions, then verify all direct and proxied endpoints. | +| `pnpm dev -- --port 5175` passed `--port` as a Next project directory | 1 | Use the repository script's supported `pnpm dev --port 5175` argument form. |