Problem
The slash command palette only opens when the entire input starts with / and contains no whitespace:
- Palette query:
value.startsWith("/") && !/\s/.test(value.slice(1)) in components/ChatInput.tsx
- Built-in command dispatch also only fires when the message starts with
/
This means you can't describe your task first and then attach a skill. In Codex CLI / Claude Code, a common flow is:
refactor the auth module to use refresh tokens /my-skill
…where typing / after a space (or anywhere at the caret) opens the skill palette, and selecting a skill inserts the command at the caret. In pi-web today that flow is impossible — you have to open the palette first, before typing anything.
Proposal
Make the slash trigger caret-based, mirroring how the @ file autocomplete already works in the same component ("recomputed from the text before the caret on every change/caret move"):
- Detect a
/ token at the caret — i.e. / at position 0, or preceded by whitespace, and the token up to the caret contains no whitespace.
- Open the palette anchored to that token; filter as the user keeps typing within the token.
- On select, replace only the
/query token at the caret with the chosen command, preserving the surrounding text.
- Keep the existing start-of-input behavior unchanged (it becomes a special case of the above).
Open question: should built-in command dispatch (onBuiltinCommand) also accept mid-message /command, or stay start-of-message only? I'd lean toward keeping dispatch as-is (start only) and only widening the palette trigger — inserting a skill mid-text expands to text the model sees, which matches CLI behavior.
Notes
Problem
The slash command palette only opens when the entire input starts with
/and contains no whitespace:value.startsWith("/") && !/\s/.test(value.slice(1))incomponents/ChatInput.tsx/This means you can't describe your task first and then attach a skill. In Codex CLI / Claude Code, a common flow is:
…where typing
/after a space (or anywhere at the caret) opens the skill palette, and selecting a skill inserts the command at the caret. In pi-web today that flow is impossible — you have to open the palette first, before typing anything.Proposal
Make the slash trigger caret-based, mirroring how the
@file autocomplete already works in the same component ("recomputed from the text before the caret on every change/caret move"):/token at the caret — i.e./at position 0, or preceded by whitespace, and the token up to the caret contains no whitespace./querytoken at the caret with the chosen command, preserving the surrounding text.Open question: should built-in command dispatch (
onBuiltinCommand) also accept mid-message/command, or stay start-of-message only? I'd lean toward keeping dispatch as-is (start only) and only widening the palette trigger — inserting a skill mid-text expands to text the model sees, which matches CLI behavior.Notes
ChatInput.tsx(rendering side). This change is about trigger logic, so overlap should be small — I'll rebase if it lands first.