feat: show task attachments during workspace preparation (#3594)
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
---
|
||||
created: 2026-09-10
|
||||
status: done
|
||||
requirements:
|
||||
- REQ-TASKS-PROMPT-ATTACHMENTS-001
|
||||
system_design:
|
||||
- ../../specs/tasks/system-design/prompt-attachments.md
|
||||
legacy_specs: []
|
||||
---
|
||||
|
||||
# Implementation Plan: Preparation attachment previews
|
||||
|
||||
## Overview
|
||||
|
||||
Show submitted screenshots and file labels while a new task prepares its workspace.
|
||||
One sequential work order carries a session preview from task creation to chat.
|
||||
The task system owns this change because it owns submitted attachments and session identity.
|
||||
|
||||
## Evidence and root cause
|
||||
|
||||
The reported task `7a8da962-d5ba-4b6c-b9ee-92691f21e3b4` has two PNG descriptors
|
||||
in its first stored user message. The supplied screenshot shows its text-only
|
||||
row above worktree preparation. A read-only source trace confirms:
|
||||
|
||||
- `prepareStartAgentSession` creates the session without passing attachment display data.
|
||||
- `postLaunchCreated` / `postLaunchStart` call `recordInitialMessage` after launch.
|
||||
- `buildTaskDescriptionMessage` creates a synthetic row without attachment metadata.
|
||||
- `chat-message.tsx` renders images and file labels from that missing metadata.
|
||||
|
||||
Reproduce with a new task containing text and two images while workspace setup
|
||||
is held pending. The fallback has text, but no attachments. No live instance
|
||||
was mutated, and no runtime reproduction or permanent test has been run yet.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope: file-backed task-create attachments during session preparation,
|
||||
prepare-only creation, reload, failure, stored-message replacement, and phone parity.
|
||||
|
||||
Out of scope: upload limits, new delivery modes, queue changes, additional-session
|
||||
prompt redesign, legacy inline preview backfill, and changing when the backend
|
||||
records a delivered initial message. A queued task without a session is outside
|
||||
this workspace-preparation view.
|
||||
|
||||
## Technical approach
|
||||
|
||||
Follow the existing [attachment design](../../specs/tasks/system-design/prompt-attachments.md#initial-preview-during-workspace-preparation).
|
||||
Extend the internal preparation options in `session_launch.go` and
|
||||
`task_operations.go`; forward display data from both task-create prepare branches
|
||||
in `task_http_handlers.go`. Persist bounded `initial_prompt_preview` metadata
|
||||
after attachment admission and before session publication/workspace work.
|
||||
|
||||
Read the resolved session through `useSessionState` / `useSessionData`, then
|
||||
normalize its preview in `useProcessedMessages`. Render with the existing
|
||||
attachment components. Preserve all current history-exhaustion guards and
|
||||
stored-message precedence. Keep snapshot data out of agent dispatch and turn accounting.
|
||||
|
||||
## ASCII UI preview
|
||||
|
||||
UI-01: Task Chat during workspace preparation, shared desktop/phone composition.
|
||||
|
||||
```text
|
||||
Before After
|
||||
+-------------------------+ +-------------------------+
|
||||
| Submitted text | | [image 1] [image 2] |
|
||||
+-------------------------+ | [notes.txt] |
|
||||
Preparing environment... | Submitted text |
|
||||
Create worktree +-------------------------+
|
||||
Preparing environment...
|
||||
Create worktree
|
||||
```
|
||||
|
||||
The user row stays above progress. Phone attachments wrap within the existing
|
||||
single-column Chat view; Chat owns vertical scrolling. Image taps open the
|
||||
existing viewer. Files retain their existing compact labels. Grouping and
|
||||
order are required; spacing is illustrative. Reuse localized controls.
|
||||
|
||||
Attachment-only: omit the text area and keep the attachment row. No attachments:
|
||||
keep the current text row. Failure: keep the preview above the existing error.
|
||||
After launch: show only the stored user message with its attachments.
|
||||
These states cover AC-TASKS-PROMPT-ATTACHMENTS-001.8 through .11.
|
||||
|
||||
## Tests
|
||||
|
||||
- `.8`, `.9`: new `task_http_handlers_initial_preview_test.go` and
|
||||
`initial_prompt_preview_test.go` verify the snapshot exists before background
|
||||
preparation, survives a fresh session read, and cannot start an agent itself.
|
||||
- `.8`, `.10`: `use-processed-messages-fallback.test.ts` covers descriptor-only
|
||||
images/files, empty text, late metadata, stored-row replacement, unknown
|
||||
history, older history, malformed entries, and session switches.
|
||||
- `.11`: rendered checks use existing image/file controls and verify unavailable
|
||||
content does not remove other content.
|
||||
- Preserve claim-denial and initial-message dedup tests; a preview is not a turn.
|
||||
|
||||
## E2E tests
|
||||
|
||||
Add `e2e/tests/task/preparation-attachments.spec.ts` (`chromium`) and
|
||||
`e2e/tests/task/mobile-preparation-attachments.spec.ts` (`mobile-chrome`).
|
||||
Use shared fixtures and a controlled preparation barrier, not a fixed sleep.
|
||||
On a disposable repository, a setup script can wait for a test-owned release
|
||||
file; always release the barrier and remove owned fixture data in `finally`.
|
||||
Verify the selected executor actually runs the barrier before asserting UI.
|
||||
|
||||
Create a task with two uploaded images and a resource file through the UI.
|
||||
While preparation is pending, open an image, close it, inspect the file label,
|
||||
reload, and verify the same attachments. Release preparation and assert exactly
|
||||
one stored initial message. Add preparation-failure and inaccessible-content
|
||||
cases. Phone checks use taps and assert zero document horizontal overflow.
|
||||
These scenarios cover `.8` through `.11`; capture the preparation view for comparison to UI-01.
|
||||
|
||||
## Work orders
|
||||
|
||||
- [x] [Task 01: Show initial attachment previews](task-01-initial-attachment-previews.md)
|
||||
|
||||
## Verification results
|
||||
|
||||
- `python3 scripts/lint-spec-files.py --all`: passed.
|
||||
- `python3 scripts/lint-spec-files.test.py`: passed, 36 tests.
|
||||
- `git diff --check`: passed.
|
||||
- Worktree status confirms the requirement/design edits and new plan/work order.
|
||||
- Implementation, runtime reproduction, and browser checks: not run in this design turn.
|
||||
|
||||
Implementation verification: targeted backend suites passed; hook tests passed
|
||||
(12); TypeScript, native builds, and the E2E web build passed. Managed desktop
|
||||
tests passed (2), and managed phone tests passed (1), with retries disabled.
|
||||
Both captured views show the images and file label during preparation. See the
|
||||
work order for commands, fixture corrections, and detailed results.
|
||||
|
||||
## Risks
|
||||
|
||||
- Preview data could accidentally dispatch twice if reused as launch input.
|
||||
- Session reuse or stale hydration could show another session's attachments.
|
||||
- Relaxing fallback history guards could invent an initial message in old history.
|
||||
- Metadata persistence must preserve unrelated keys and precede background work.
|
||||
|
||||
The public task attachment guide now explains preparation previews and distinguishes
|
||||
them from successful agent delivery. See the work order for implementation results.
|
||||
@@ -0,0 +1,177 @@
|
||||
---
|
||||
id: "01-initial-attachment-previews"
|
||||
title: "Show initial attachment previews"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
requirements:
|
||||
- REQ-TASKS-PROMPT-ATTACHMENTS-001
|
||||
acceptance_criteria:
|
||||
- AC-TASKS-PROMPT-ATTACHMENTS-001.8
|
||||
- AC-TASKS-PROMPT-ATTACHMENTS-001.9
|
||||
- AC-TASKS-PROMPT-ATTACHMENTS-001.10
|
||||
- AC-TASKS-PROMPT-ATTACHMENTS-001.11
|
||||
system_design:
|
||||
- ../../specs/tasks/system-design/prompt-attachments.md
|
||||
---
|
||||
|
||||
# Task 01: Show initial attachment previews
|
||||
|
||||
## Summary
|
||||
|
||||
Carry a validated session preview from task creation to the preparation transcript.
|
||||
Reuse the existing attachment controls and replace the preview when stored history arrives.
|
||||
|
||||
## In scope
|
||||
|
||||
- Internal preparation option and persisted session preview before publication.
|
||||
- Session metadata normalization, synthetic message composition, and attachment types.
|
||||
- Focused backend, hook, desktop, and phone regression coverage from the plan.
|
||||
|
||||
## Out of scope
|
||||
|
||||
Agent delivery changes, new storage tables or APIs, queues, and legacy inline preview backfill.
|
||||
|
||||
## Acceptance
|
||||
|
||||
1. Backend preparation publishes the submitted preview before workspace work,
|
||||
preserves it on fresh reads and failure, and preserves claim/session isolation.
|
||||
2. Chat displays it with existing controls, handles empty text and malformed
|
||||
metadata, and replaces it without duplicates under all existing history guards.
|
||||
3. Desktop and phone E2E prove opening attachments during preparation, reload,
|
||||
success replacement, and failure behavior without overflowing the phone viewport.
|
||||
|
||||
## ASCII UI preview
|
||||
|
||||
UI-01: Task Chat during workspace preparation. See the [full state preview](plan.md#ascii-ui-preview).
|
||||
|
||||
```text
|
||||
+--------------------------+
|
||||
| [image 1] [image 2] |
|
||||
| [notes.txt] |
|
||||
| Submitted text |
|
||||
+--------------------------+
|
||||
Preparing environment...
|
||||
Create worktree
|
||||
```
|
||||
|
||||
Shared phone/desktop ordering; phone content wraps in the existing Chat scroll
|
||||
region. Image tap opens the existing viewer. Failure retains this row above
|
||||
the existing error; stored history replaces it. Covers `.8` through `.11`.
|
||||
|
||||
## Verification
|
||||
|
||||
Run from the repository root. Bootstrap dependencies once if this worktree lacks them.
|
||||
Write and run the backend/hook regression before production edits. The backend
|
||||
test must fail because preparation has no snapshot; the hook test must fail
|
||||
because the initial row has no attachment metadata, not because a selector is missing.
|
||||
|
||||
```bash
|
||||
(cd apps && pnpm install --frozen-lockfile)
|
||||
(cd apps/backend && go test ./internal/task/handlers -run 'Test.*InitialPreview' -count=1)
|
||||
(cd apps/backend && go test ./internal/task/models -run 'TestInitialPromptPreview' -count=1)
|
||||
(cd apps/backend && go test ./internal/orchestrator -run 'Test.*(InitialPromptPreview|LaunchSession|InitialPrompt)' -count=1)
|
||||
(cd apps/web && pnpm exec vitest run hooks/use-processed-messages-fallback.test.ts)
|
||||
(cd apps/web && pnpm run typecheck)
|
||||
(cd apps/web && pnpm e2e:run --project chromium tests/task/preparation-attachments.spec.ts)
|
||||
(cd apps/web && pnpm e2e:run --project mobile-chrome tests/task/mobile-preparation-attachments.spec.ts)
|
||||
python3 scripts/lint-spec-files.py --all
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Run changed-file ESLint and Go formatting checks. Include any additional test
|
||||
files changed by implementation in this command list before marking complete.
|
||||
Managed E2E builds current assets; do not reuse a stale build. Check discovered
|
||||
test counts and compare the captured phone view with UI-01.
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/backend/internal/task/handlers/task_http_handlers.go`
|
||||
- `apps/backend/internal/task/handlers/task_http_handlers_initial_preview_test.go` (new)
|
||||
- `apps/backend/internal/orchestrator/session_launch.go`
|
||||
- `apps/backend/internal/orchestrator/task_operations.go`
|
||||
- `apps/backend/internal/orchestrator/initial_prompt_preview_test.go` (new)
|
||||
- `apps/backend/internal/task/models/initial_prompt_preview.go` (new typed metadata helper if needed)
|
||||
- `apps/web/components/task/chat/use-chat-panel-state.ts`
|
||||
- `apps/web/hooks/use-processed-messages.ts`
|
||||
- `apps/web/hooks/use-processed-messages-fallback.test.ts`
|
||||
- `apps/web/components/task/chat/messages/chat-message.tsx`
|
||||
- `apps/web/e2e/tests/task/preparation-attachments.spec.ts` (new)
|
||||
- `apps/web/e2e/tests/task/mobile-preparation-attachments.spec.ts` (new)
|
||||
- A shared preparation fixture helper under `apps/web/e2e/helpers/`.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None. Use the existing attachment claim service, session metadata persistence,
|
||||
history initialization state, and attachment renderer.
|
||||
|
||||
## Risks
|
||||
|
||||
Do not pass display snapshots as a second launch prompt. Do not attach task-wide
|
||||
files to sibling sessions or change fallback history eligibility. Preserve
|
||||
passthrough prepare upgrades and unrelated session metadata.
|
||||
|
||||
## Parallelism
|
||||
|
||||
`sequential`
|
||||
|
||||
## Inputs
|
||||
|
||||
- [Requirements](../../specs/tasks/requirements/prompt-attachments.md), `.8` through `.11`.
|
||||
- [Design](../../specs/tasks/system-design/prompt-attachments.md#initial-preview-during-workspace-preparation).
|
||||
- Existing `use-processed-messages-fallback.test.ts` and `mixed-attachment-layout.ts` patterns.
|
||||
- Root and scoped AGENTS.md, `/tdd`, `/e2e`, and `/mobile-parity`.
|
||||
|
||||
## Results
|
||||
|
||||
Implementation adds a display-only session snapshot before preparation publication.
|
||||
The frontend validates descriptors and reuses the existing image controls and file
|
||||
labels. History guards, session isolation, and stored-message precedence remain intact.
|
||||
Synthetic rows cannot be favorited. Public task documentation explains the preview.
|
||||
|
||||
- Behavioral RED: the hook omitted attachment metadata; the task-create handler
|
||||
omitted the preview from its preparation request. Both regressions passed after wiring.
|
||||
- Hook regression suite: 12 tests passed, including late hydration, attachment-only
|
||||
prompts, malformed descriptors, history guards, and stored-message replacement.
|
||||
- TypeScript checking passed. Changed-file ESLint reported no errors.
|
||||
- Model descriptor test passed. Public docs tests passed (62 tests); validation
|
||||
passed for 46 pages. Specification lint and whitespace checks passed.
|
||||
- Desktop and phone E2E scenarios were added. The initial managed browser run
|
||||
stopped during backend build because the shared disk filled; no browser assertion ran.
|
||||
- Backend verification retries encountered disappearing shared cache and temporary
|
||||
build files. A retry uses a private cache and build directory.
|
||||
|
||||
Final targeted backend checks passed for models, handlers, and orchestrator.
|
||||
The orchestrator command includes existing initial-prompt and launch-session tests.
|
||||
The preview-write failure test first demonstrated a stranded CREATED session, then
|
||||
passed with the existing launch-failure handler. The sibling-session fixture now
|
||||
sets its workspace ready before creating the sibling, as the product requires.
|
||||
The final hook run passed all 12 tests with `--silent`, after a console-forwarding
|
||||
teardown failure on a prior run. TypeScript and changed-hook lint passed again.
|
||||
|
||||
Final browser verification passed with fresh host-only artifacts. Build commands:
|
||||
|
||||
```bash
|
||||
(cd apps/backend && make build-agentctl build-kandev build-mock-agent e2e-plugin-package GOFLAGS=-p=1)
|
||||
(cd apps/web && pnpm build:e2e)
|
||||
(cd apps/web && pnpm e2e:run --host --no-build --project chromium tests/task/preparation-attachments.spec.ts --retries=0)
|
||||
(cd apps/web && pnpm e2e:run --host --no-build --project mobile-chrome tests/task/mobile-preparation-attachments.spec.ts --retries=0)
|
||||
```
|
||||
|
||||
- Desktop: 2 passed. Phone: 1 passed. Retries were disabled; cleanup also passed.
|
||||
- Screenshots were inspected against UI-01. Both layouts retain the image controls,
|
||||
file label, and prompt. The phone view has no document horizontal overflow.
|
||||
- Browser coverage uses a controlled setup barrier and tests image opening,
|
||||
reload, unavailable image content, and replacement by one saved user message.
|
||||
The second desktop scenario checks non-fatal setup warnings. Terminal failure
|
||||
persistence is covered at the backend boundary.
|
||||
- Initial browser failures were fixture issues: cleanup needed explicit consent
|
||||
to discard attachment-staging files; fetch responses expose `ok` as a property;
|
||||
setup-script failures produce `completed_with_warnings`, not a terminal error.
|
||||
- The hook and handler provided behavioral RED evidence before implementation.
|
||||
Browser checks were added after the minimal fix to verify the rendered data path.
|
||||
- Final changed-file ESLint: no errors; two test-file size/duplication warnings.
|
||||
Go formatting and whitespace checks passed.
|
||||
|
||||
No production agent-delivery behavior or remote executor build was changed.
|
||||
@@ -302,6 +302,8 @@ Folders are live host paths and are available only to **Local/Local PC** and **W
|
||||
|
||||
The task prompt supports image, audio, and resource attachments. Kandev accepts at most 10 files per submission, with a 100 MiB raw limit per file and a 100 MiB raw aggregate limit. Files are uploaded over authenticated HTTP before the task or message is submitted, so the task-create JSON and WebSocket frames carry attachment descriptors rather than base64 file contents. An upload that is still in progress or has failed must finish or be retried before the prompt can be sent. Removing a staged attachment discards its private upload; unclaimed uploads expire automatically after 24 hours. This prompt-attachment limit does not change the separate 10 MB task-document upload contract.
|
||||
|
||||
During workspace preparation, the initial message shows your uploaded screenshots and file labels. You can open image previews before the agent starts. The preview survives a page reload and remains visible if preparation fails. It does not indicate successful delivery to the agent.
|
||||
|
||||
Creating a fresh local branch is available only with the local executor. If the checkout is dirty, Kandev lists the affected paths and requires explicit consent before discarding those local changes. If another path becomes dirty after the warning, creation fails with a conflict and asks for consent again. Save or commit work before approving this operation.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
status: draft
|
||||
system: tasks
|
||||
created: 2026-08-04
|
||||
updated: 2026-09-02
|
||||
updated: 2026-09-10
|
||||
owners:
|
||||
- Kandev team
|
||||
---
|
||||
@@ -41,6 +41,21 @@ This document is the migrated task-system source for the capability. The source
|
||||
message delivered into a generating turn, the system shall surface a durable
|
||||
error for that message and shall not deliver an attachment reference whose
|
||||
bytes are absent from the session.
|
||||
- **AC-TASKS-PROMPT-ATTACHMENTS-001.8:** While a newly created task session
|
||||
prepares its workspace, its initial message preview shall show the submitted
|
||||
text, image previews, and file labels before the agent starts. An attachment-only
|
||||
submission shall show its attachments without an empty text bubble.
|
||||
- **AC-TASKS-PROMPT-ATTACHMENTS-001.9:** Reloading that session during
|
||||
preparation, or after preparation fails, shall preserve its initial preview.
|
||||
The preview shall not imply successful agent delivery or hide preparation errors.
|
||||
- **AC-TASKS-PROMPT-ATTACHMENTS-001.10:** When a stored user message becomes
|
||||
visible, the transcript shall replace the initial preview without duplicate
|
||||
messages or attachments. A different session shall not inherit that preview.
|
||||
Unloaded older history shall not cause the preview to reappear.
|
||||
- **AC-TASKS-PROMPT-ATTACHMENTS-001.11:** Desktop and phone users shall be
|
||||
able to open preparation image previews and inspect file labels through the
|
||||
existing attachment controls. Preview failures shall not hide prompt text
|
||||
or other attachments, and the phone transcript shall remain within the viewport.
|
||||
|
||||
## Migrated source detail
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ system: tasks
|
||||
requirements:
|
||||
- REQ-TASKS-PROMPT-ATTACHMENTS-001
|
||||
created: 2026-09-01
|
||||
updated: 2026-09-10
|
||||
owners:
|
||||
- Kandev team
|
||||
---
|
||||
@@ -111,6 +112,94 @@ backend derives those values from authenticated and persisted state.
|
||||
Task-scoped idempotency applies only when the stored task matches. Session
|
||||
scoping remains strict when the stored claim contains a session identity.
|
||||
|
||||
## Initial preview during workspace preparation
|
||||
|
||||
This proposed extension covers AC-TASKS-PROMPT-ATTACHMENTS-001.8 through
|
||||
AC-TASKS-PROMPT-ATTACHMENTS-001.11. The task system owns the submitted
|
||||
attachment set and its session binding. Transcript history still follows the
|
||||
[UI history design](../../ui/system-design/task-prompt-transcript-visibility.md).
|
||||
|
||||
The task-create handlers currently prepare a session synchronously, then start
|
||||
it asynchronously. `prepareStartAgentSession` does not forward the submitted
|
||||
text or attachments. `postLaunchCreated` and `postLaunchStart` record the
|
||||
initial user message after launch. Until then, `useProcessedMessages` builds a
|
||||
text-only task-description fallback.
|
||||
|
||||
Pass an internal, display-only initial-preview value through the task-create
|
||||
prepare path, including prepare-only creation. Persist it in the target
|
||||
session's metadata as `initial_prompt_preview` before publishing the created
|
||||
session or starting workspace preparation. Use an internal preparation option;
|
||||
do not make preview data a second agent-dispatch input or change passthrough
|
||||
prepare upgrades. The value contains `content` and `attachments`, using the
|
||||
existing display descriptor fields: `attachment_id`, `type`, `name`,
|
||||
`mime_type`, `size_bytes`, and `delivery_mode`. Only validated file-backed
|
||||
descriptors from the successful task attachment claim enter this value.
|
||||
Do not copy inline bytes, storage paths, hidden prompts, or arbitrary metadata.
|
||||
|
||||
Use the existing session metadata persistence and session publication path.
|
||||
No new endpoint or table is needed. An atomic metadata-key update must preserve
|
||||
other session keys. A failed preview write must stop this preparation path
|
||||
before background work starts and use its existing failure handling.
|
||||
Reused sessions must not acquire another initial preview. Legacy inline-only
|
||||
attachments keep their existing post-launch behavior; this extension targets
|
||||
the file-backed web submission path.
|
||||
|
||||
The snapshot remains session-owned across reload and preparation failure. It
|
||||
is display data, not evidence of delivery, a turn, a prompt ordinal, or a retry
|
||||
queue. Retain it with the session so a delayed metadata hydration cannot revive
|
||||
a deleted key. Existing session deletion removes it. Stored user messages are
|
||||
always authoritative once loaded. Retries must not copy the snapshot into a
|
||||
different session or alter attachment claim/delivery semantics.
|
||||
|
||||
`useSessionState` already provides the resolved session. Pass its validated
|
||||
preview through `useSessionData` to `useProcessedMessages`. Validate unknown
|
||||
metadata before mapping it to `Message.metadata.attachments`; reject malformed
|
||||
entries independently. Never combine task-wide attachment inventory with the
|
||||
current session or read the transient `deferred_launch` metadata as display state.
|
||||
|
||||
Render one synthetic user row only when history is initialized, no older
|
||||
history remains, and no stored user row is visible. Prefer the session preview
|
||||
when it has text or valid attachments; otherwise preserve the existing legacy
|
||||
task-description fallback. Keep the synthetic row's existing identity and
|
||||
missing-timestamp behavior. Include the preview in memo dependencies so late
|
||||
session hydration updates the row. Do not insert it into persisted message
|
||||
state or enable persisted-message mutations for it.
|
||||
|
||||
Reuse `chat-message.tsx` image and resource attachment rendering, including
|
||||
`attachmentContentUrl` and the existing image dialog. Correct its local
|
||||
attachment type to represent optional inline bytes and file-backed IDs.
|
||||
Continue to authorize content reads through the existing attachment service.
|
||||
An inaccessible image must not remove the surrounding message or siblings.
|
||||
|
||||
### Desktop and phone composition
|
||||
|
||||
Both surfaces show the initial user row above existing preparation progress.
|
||||
Images and compact file labels wrap inside that row, above its text. The primary
|
||||
action is opening an image. No additional navigation or toolbar is introduced.
|
||||
The phone entry is the existing task Chat view. Reuse the dedicated phone
|
||||
composition in `components/task/task-layout.tsx`, the attachment controls in
|
||||
`chat-message.tsx`, and the mixed-attachment mobile E2E exemplar.
|
||||
|
||||
The transcript remains the single vertical scroll owner. Existing full-height
|
||||
layout, safe-area handling, image-dialog dismissal, focus return, and touch
|
||||
targets remain in effect. Inline attachment content fits this brief review
|
||||
task without an intermediate picker. Desktop and phone share the preview data
|
||||
and replacement logic; no responsive preference is persisted.
|
||||
|
||||
### Verification boundaries
|
||||
|
||||
Backend tests pause before workspace launch and verify persisted preview
|
||||
metadata, fresh reads, prepare-only behavior, claim rejection, and unrelated
|
||||
session isolation. Frontend tests cover descriptor mapping, attachment-only
|
||||
content, malformed metadata, late hydration, history guards, and replacement.
|
||||
Desktop and mobile browser tests open both attachments during preparation,
|
||||
reload, then observe one stored initial message after launch. Include failure
|
||||
and unavailable-content cases without suppressing existing progress errors.
|
||||
|
||||
## Implementation plans
|
||||
|
||||
- [Preparation attachment previews](../../../plans/preparation-attachment-previews/plan.md)
|
||||
|
||||
## Observability
|
||||
|
||||
Existing launch request diagnostics correlate claim errors with their task and
|
||||
|
||||
Reference in New Issue
Block a user