Skip to content

bug: a file attached to an unsent Workspace message cannot be removed from the composer #3738

Closed

Description

@vybe

Summary

A file attached to a Workspace chat message that has not been sent yet cannot be removed. The pending chip above the composer shows the file name and its upload state, but it has no × and no other way to take the file off the message: the only ways out are to send it anyway or to leave the chat. The same gap exists in the room composer.

Context

Reported from the live Workspace on the 1.0 rc line (dev @ e4e739f7). A dropped, pasted or picked file is uploaded to the agent's inbox at once (ent#524) and its chip rides the composer until Send; a pending chip that cannot be dismissed means a wrong file goes to the agent with the message. The drop composable (src/frontend/src/composables/usePortalFileDrop.js) already exposes a per-entry remove function, and the chip's own padding reserves room for a trailing control, but neither PortalConversation.vue nor PortalRoom.vue wires it.

Acceptance Criteria

  • Every pending attachment chip in the Workspace chat composer carries an × that removes that file from the outgoing message, with an accessible name that says which file it removes.
  • Clicking × never submits the composer and never selects or focuses anything else; the draft text and the other chips are untouched.
  • × works in every chip state (queued, uploading, uploaded, failed). Removing an uploading or uploaded file also deletes its uploaded copy from the agent's inbox when that upload had completed, best effort: a delete failure does not block the removal and is not shown as a chip error.
  • Removing the last chip hides the chip row and lifts any send-blocking state that existed only because attachments were pending (for example the discussion-answer block that attachments impose).
  • The room composer (PortalRoom.vue) gets the same affordance with the same behaviour.
  • The × follows the design system: the chip's own ink (text-current), a visible hover and focus-visible state, large enough to hit on touch, no new raw colours.
  • jsdom mount coverage in src/frontend/tests/unit/: a chip renders the ×; clicking it removes exactly that entry and calls the inbox delete only for a completed upload; the composer does not submit.

Technical Notes

  • src/frontend/src/composables/usePortalFileDrop.js — the entries list and removeAt; clear resets the batch notice too.
  • src/frontend/src/components/portal/PortalConversation.vue — the pending chip row (data-testid="portal-attachment-chip") and the composable destructure; discussionAnswerBlocked reads attachments.length.
  • src/frontend/src/components/portal/PortalRoom.vue — the room's chip row (data-testid="portal-room-attachment-chip").
  • src/frontend/src/stores/clientPortal.js — deleteUpload(agentName, filename).
  • Existing composer specs: src/frontend/tests/unit/portalComposerWiring.spec.js, roomComposerChain.spec.js.

Activity

  1. added
    complexity-lowComplexity: low (board points 1-3)
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    on Oct 14, 2026
  2. vybe commented on Oct 14, 2026

    @vybe
    ContributorAuthor

    Draft PR: #3743 — stacked on #3742 (base feature/3737-overflow-starred-row), tip 099c59c. Review: MERGEABLE; two informational findings fixed, one recorded; cso clean. Merges after #3742, retargeted to dev.

  3. vybe commented on Oct 14, 2026

    @vybe
    ContributorAuthor

    /validate-pr on #3743, round 2: APPROVE (review by trinity-ability 2026-10-14 22:20Z on tip a4a22da; 203/203 targeted tests; the round-1 blocker — no executing test for the escalation hand-off lock — closed by portalAttachmentChipHandoff.mount.spec.js, all three lock mutations now red). PR marked ready for review. Merge order: #3742 first, then retarget #3743 to dev and let the dev-only checks (Analyze ×2, backend-unit-test) run before merging.

  4. removed
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    on Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions