Agent Plugins
Add prompt buttons to the Stoa AI agent's composer toolbar with agent plugins.
Agent plugins add prompt buttons to the AI agent's composer toolbar, between the push-to-talk button and the send button. Clicking a button pre-fills the composer with the prompt text.
Three display modes controlled by @toolbar or the toolbar field in the output:
Pills (default)
Flat inline buttons on the toolbar row:
// @stoa-plugin
// @name Code Prompts
// @type agent
// @icon Code
// @toolbar pills
module.exports = {
render() {
return {
type: 'prompts',
prompts: [
{ label: 'Review file', prompt: 'Review the currently open file for bugs and improvements.' },
{ label: 'Write tests', prompt: 'Write comprehensive unit tests for the currently open file.' },
]
}
}
}Menu
A single dropdown button that opens a grouped prompt list. Best for lots of prompts:
// @stoa-plugin
// @name Sprint Tools
// @type agent
// @icon BarChart3
// @toolbar menu
module.exports = {
render() {
return {
type: 'prompts',
toolbar: 'menu',
menuLabel: 'Sprint',
prompts: [
{ label: 'Sprint status', prompt: 'What is the current sprint status?', icon: '\ud83d\udcca', group: 'Status' },
{ label: 'Blockers', prompt: 'List all current blockers.', icon: '\ud83d\udeab', group: 'Status' },
{ label: 'Review PR', prompt: 'Review the most recent pull request.', icon: '\ud83d\udd0d', group: 'Code' },
{ label: 'Write changelog', prompt: 'Write a changelog for recent changes.', icon: '\ud83d\udcdd', group: 'Code' },
]
}
}
}Icons
Compact emoji-only buttons. Best for quick actions:
// @stoa-plugin
// @name Quick Actions
// @type agent
// @icon Zap
// @toolbar icons
module.exports = {
render() {
return {
type: 'prompts',
prompts: [
{ label: 'Review', prompt: 'Review the currently open file.', icon: '\ud83d\udd0d' },
{ label: 'Tests', prompt: 'Write tests for this file.', icon: '\ud83e\uddea' },
{ label: 'Explain', prompt: 'Explain how this code works.', icon: '\ud83d\udca1' },
]
}
}
}Prompt fields
| Field | Required | Description |
|---|---|---|
label | Yes | Short text shown on the button |
prompt | Yes | Full text that fills the composer when clicked |
icon | No | Emoji shown before the label (or as the button in icons mode) |
group | No | Group header in menu mode |
Output fields
| Field | Description |
|---|---|
toolbar | 'pills', 'menu', or 'icons' — overrides @toolbar from the header |
menuLabel | Custom label for the menu dropdown button (defaults to plugin name) |
prompts | Array of prompt objects |
Context-aware prompts
Use {activeFile} and {activeFileShort} placeholders in prompt text and labels. They're replaced at click time with the file currently open in the editor:
module.exports = {
render() {
return {
type: 'prompts',
prompts: [
{ label: 'Review {activeFileShort}', prompt: 'Review {activeFile} for bugs and improvements.' },
]
}
}
}When viewing src/components/Header.tsx:
- Label shows: Review Header.tsx
- Clicking sends: Review src/components/Header.tsx for bugs and improvements.
When no file is open:
- In labels, placeholders are stripped
- In prompts, fallback text is used:
{activeFile}becomes "the currently open file"
Tip
Placeholders update instantly when the user switches files — no plugin re-execution needed.
Overflow
When multiple agent plugins or many prompts exceed the available toolbar width, excess items automatically collapse into a ... overflow dropdown. Menus are the most compact and collapse last.