Skip to content

spec: align composer placeholders with conversation state #6376

Description

@serge-the-hedge

Problem Statement

The composer currently gives web users continuation-oriented guidance when they begin a new conversation and basic capability guidance after a conversation has already started. This happens because web chooses its ordinary placeholder from session phase: a new draft has no session and is therefore treated as disconnected, while an existing thread commonly has a ready or running session.

Composer guidance also differs between clients. Web, desktop, and mobile use separate strings and separate decisions even though they are describing the same two moments: beginning a conversation and continuing an existing thread. This makes the wording easy to reverse or allow to drift across clients.

Solution

Choose ordinary composer guidance from conversation state rather than session state. A new conversation receives concise guidance for making an initial request and discovering composer capabilities. An existing conversation receives guidance for asking for changes, adding context, or attaching images.

Define the canonical new-conversation and existing-conversation copy once in client runtime and let each client select the appropriate conversation state. Web and desktop select dynamically from the rendered conversation, including optimistic messages. Mobile's new-task composer selects the new-conversation copy, while its thread composer selects the existing-conversation copy.

Special composer states remain owned by their current clients and continue to override the ordinary conversation placeholder.

User Stories

  1. As a user starting a new conversation, I want the composer to invite an initial request, so that I understand what to ask before any work has happened.
  2. As a user starting a new conversation, I want the composer to surface useful composer capabilities, so that I can discover file mentions, skills, commands, and supported attachments.
  3. As a user continuing an existing thread, I want the composer to invite changes and additional context, so that the guidance matches the work already in progress.
  4. As a user continuing an existing thread, I want attachment guidance to remain available, so that I know I can add visual context after the initial request.
  5. As a web user, I want a draft with no rendered messages to receive new-conversation guidance, so that the absence of a provider session does not make the composer sound like a follow-up.
  6. As a web user, I want the placeholder to switch after my first message appears optimistically, so that the composer responds immediately rather than waiting for server projection or session readiness.
  7. As a web user reopening a stopped, interrupted, or errored thread, I want existing-conversation guidance, so that a disconnected session is not mistaken for a new conversation.
  8. As a desktop user, I want the same guidance as the web client it wraps, so that the product behaves consistently across local desktop and browser use.
  9. As a mobile user creating a task, I want the same new-conversation intent as web, so that changing clients does not change the meaning of the composer guidance.
  10. As a mobile user viewing an existing thread, I want continuation-oriented guidance, so that the composer acknowledges the established conversation.
  11. As a user moving between clients, I want the core composer wording to stay aligned, so that each surface teaches the same interaction model.
  12. As a user responding to an approval, I want approval-specific guidance to take precedence, so that ordinary placeholder copy does not obscure the required action.
  13. As a user answering an agent question, I want question-specific guidance to take precedence, so that I understand how my answer will be used.
  14. As a user reviewing a proposed plan, I want plan-specific guidance to take precedence, so that I understand how to refine or implement the plan.
  15. As a user who has not selected a project, I want project-selection guidance to take precedence, so that I know why I cannot begin the thread.
  16. As a user without an available provider, I want provider guidance to take precedence, so that the composer explains the actual blocking condition.
  17. As a maintainer changing composer wording, I want the canonical ordinary copy to live in one module, so that web, desktop, and mobile do not drift independently.
  18. As a maintainer, I want clients to pass semantic conversation state rather than session details into shared presentation logic, so that connection lifecycle changes cannot reverse the guidance again.
  19. As a maintainer, I want the web font preview to choose an example deliberately, so that a settings sample is not mistaken for live conversation-state behavior.

Implementation Decisions

  • The ordinary composer state has two semantic values: new conversation and existing conversation.
  • A shared client-runtime presentation module owns the canonical text for those two values. It is a pure TypeScript module with no React, React Native, session, provider, or orchestration dependencies.
  • The shared interface accepts semantic conversation state. It does not accept session phase or expose client-specific rendering concerns.
  • Web derives conversation state from the rendered conversation rather than session phase. Optimistic messages count as existing conversation content so the placeholder changes immediately after dispatch.
  • Desktop inherits the web behavior and requires no separate adapter.
  • The mobile new-task composer selects new-conversation guidance. The mobile thread composer selects existing-conversation guidance.
  • Approval requests, pending user input, proposed-plan follow-up, project selection, provider availability, and other special states retain their current client-owned guidance and precedence.
  • The shared module does not become a common visual element. Web and mobile retain their existing editor implementations because they use different rendering platforms.
  • The font settings preview explicitly selects one canonical placeholder as sample content; it does not infer conversation state.
  • This change does not alter contracts crossing the wire, persisted orchestration state, providers, sessions, or server behavior.
  • Exact final wording may be editorially refined during implementation, but it must preserve the distinction between beginning a conversation and continuing one, and must remain canonical across clients.

Testing Decisions

  • No automated test will be added for the two-case copy mapping. Such a test would duplicate the string literals and would not detect the reported failure at the client call site.
  • No large web or mobile composer rendering harness will be introduced solely for this change. Existing composer modules require substantial unrelated setup, and the resulting test would be disproportionate to the behavior.
  • No separate client tests will duplicate the canonical strings.
  • Verification will inspect each client call site: web dynamically selects new versus existing conversation state; mobile new-task selects new; mobile thread selects existing; and the font preview makes an explicit sample choice.
  • Targeted typechecks will cover client runtime, web, and mobile, proving that every consumer uses the shared interface correctly.
  • Integrated visual verification is optional and should only be performed when explicitly requested, following the repository's client-testing guidance.
  • Automated tests should be introduced later if placeholder selection gains meaningful branching behavior, such as localization, capability-dependent wording, additional conversation states, or shared precedence rules.

Out of Scope

  • Refreshing local Git status or changing branch-picker behavior.
  • Foreground or background Git polling.
  • Redesigning the composer editor or composer chrome.
  • Moving special-state placeholder precedence into client runtime.
  • Sharing React or React Native visual elements between clients.
  • Localization infrastructure.
  • Changing provider commands, skills, file mentions, or attachment behavior.
  • Changing session lifecycle or the meaning of disconnected state.
  • Adding new composer capabilities merely because the placeholder mentions existing ones.

Further Notes

  • In the current web behavior, a missing session, stopped session, interrupted session, and errored session all map to disconnected. That is why session phase cannot represent whether a conversation is new.
  • The shared presentation module is intended to provide locality for editorial changes, not to grow into a broad composer-state engine.
  • The implementation should keep the copy concise enough for narrow web and mobile composer layouts.
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions