Skip to content

Paste directives into the composer - #74651

Merged
OutThisLife merged 3 commits into
mainfrom
bb/composer-paste-directives
Jul 30, 2026
Merged

Paste directives into the composer#74651
OutThisLife merged 3 commits into
mainfrom
bb/composer-paste-directives

Conversation

@OutThisLife

Copy link
Copy Markdown
Collaborator

A /command or @ref typed into the composer chips as it's committed. The same text pasted did not: appendComposerContents — the one builder every paste goes through — recognized @kind:value refs and nothing else. Slash commands had a single leading-token special case in renderComposerContents, which paste never calls, so pasting /clean dropped a dead token into the composer while typing it produced a pill.

Both directive kinds now hydrate from one ordered span walk, in the main composer and the inline edit composer alike.

Paste is scanned as inert text rather than live keystrokes, which changes two answers:

  • A command ending the paste is complete, not half-typed, so it chips (a typed /wor still stays editable — that token belongs to the popover).
  • The insertion point's own token boundary decides the leading token: foo + a pasted /clean is foo/clean, not a command. A chip edge counts as a boundary, matching how trigger detection reads the line.

Recognition answers on exactly the terms the typed path uses, or hydration would invent pills the popover would never have committed: no-arg commands only (/goal ship it keeps its prose tail), paths left alone (/usr/local/bin), and built-ins as invocations only — /new acts on the app, so it means nothing dropped mid-sentence, while a skill reads as "handle this part with X".

Two repaint sites also hand the editor finished text — the main composer's programmatic draft writes and the edit composer opening a sent message — and now hydrate commands too. The edit composer was showing plain text for a message the transcript had rendered with a pill a moment earlier.

@alt-glitch alt-glitch added type/feature New feature or request comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have labels Jul 30, 2026
…atch typed

The composer chips a `/command` when it's picked or accepted from the
popover. Text that arrives whole — a paste, a restored draft, an undo
step — never passes through that path, so nothing recognizes the
commands in it.

Extract that recognition into a scanner that answers on the same terms
the typed path uses: no-arg commands only, no paths, built-ins as
invocations while skills may also be named mid-prose, and a trailing
token still-typed unless the caller says the text is inert.
`appendComposerContents` — the one builder every paste goes through —
only ever chipped `@kind:value` refs. Slash commands had a single
leading-token special case in `renderComposerContents`, which paste
doesn't call, so a pasted `/clean` landed as dead text while the same
text typed by hand became a pill.

Both directive kinds now hydrate from one ordered span walk, with `@`
refs winning a tie so a slash inside a quoted ref value stays part of
that value. Paste additionally scans as inert text: a command ending the
paste is complete rather than half-typed, and the insertion point's own
token boundary decides the leading token, so `foo` + `/clean` stays
`foo/clean`.

`textBeforeCaret`'s chip-atomic serialization moves to rich-editor as
`serializeTextBefore` — the paste path needs the same "a chip edge is a
token boundary" reading that trigger detection does.
Two repaint sites hand the editor text that is finished rather than
mid-keystroke: the main composer's programmatic draft writes (restore,
insert, history recall) and the inline edit composer opening a sent
message. Both now render with `trailingCommitted`, so a command ending
that text chips instead of reading as a half-typed token — the edit
composer in particular showed plain text for a message the transcript
had just rendered with a pill.

Regression tests cover the paste path: a command ending the paste, one
named mid-prose beside a ref, a path left alone, a paste landing against
a word, and one landing after an existing chip.
@OutThisLife
OutThisLife force-pushed the bb/composer-paste-directives branch from 916f7b6 to 422ecfe Compare July 30, 2026 07:01
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 422ecfe

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

1 visual diff.

inline evidence is publishing...

@OutThisLife
OutThisLife enabled auto-merge July 30, 2026 07:10
@OutThisLife
OutThisLife merged commit 866c9ad into main Jul 30, 2026
34 checks passed
@OutThisLife
OutThisLife deleted the bb/composer-paste-directives branch July 30, 2026 07:25
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…aste-directives

Paste directives into the composer
33hodl pushed a commit to 33hodl/hermes-agent that referenced this pull request Aug 12, 2026
…aste-directives

Paste directives into the composer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants