Replace the composer textarea with a Tiptap markdown editor

The composer now writes markdown with bold, italic, strike, code,
links, quotes and lists, from shortcuts, markdown typing or a bubble
over the selection. @ mentions a bot and # a workspace, shown as chips
and saved as [bot:ID] / [workspace:ID]. Text selected in a message can
be quoted into the composer. User messages render as markdown, and
replies tell the bot who and what the user mentioned.

Adds an ESM stand-in for use-sync-external-store, since bunext keeps
React external in page bundles and the CommonJS original requires it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-20 05:48:23 +01:00
co-authored by Claude Opus 5.5
parent e2093b0df6
commit 1208eac6b7
51 changed files with 1618 additions and 126 deletions
+13 -2
View File
@@ -18,9 +18,16 @@ export const TakeOverRefHrefPrefix = "#take-over-";
*/
export const BotRefHrefPrefix = "#bot-";
/**
* The link target a workspace ref (`workspaceRef`) becomes, e.g.
* `#workspace-2`. The chat renders these as links to that workspace.
*/
export const WorkspaceRefHrefPrefix = "#workspace-";
/**
* Turns every computer ref (`[computer:3]`) and take-over ref
* (`[take-over:3:browser]`) and bot ref (`[bot:3]`) in a message into a markdown link, so it
* (`[take-over:3:browser]`), bot ref (`[bot:3]`) and workspace ref
* (`[workspace:2]`) in a message into a markdown link, so it
* survives markdown rendering as a link the chat can swap for a button.
*/
export default function linkComputerRefs({ text }: { text: string }) {
@@ -33,5 +40,9 @@ export default function linkComputerRefs({ text }: { text: string }) {
/\[take-over:(\d+):([a-z]+)\](?!\()/g,
(_, id: string, mode: string) => `[take over](${TakeOverRefHrefPrefix}${id}-${mode})`,
)
.replace(/\[bot:(\d+)\](?!\()/g, (_, id: string) => `[bot ${id}](${BotRefHrefPrefix}${id})`);
.replace(/\[bot:(\d+)\](?!\()/g, (_, id: string) => `[bot ${id}](${BotRefHrefPrefix}${id})`)
.replace(
/\[workspace:(\d+)\](?!\()/g,
(_, id: string) => `[workspace ${id}](${WorkspaceRefHrefPrefix}${id})`,
);
}