The command palette
⌘K opens the palette. It is where plugin-owned actions surface, and it is deliberately not a second command system.
It projects intents
Every row in the palette is a projection of an intent contract that some plugin provides. There is no separate "command" object with its own registry, its own identifiers and its own permission story.
A palette row and a tenon-cli intent send of the same name invoke the same contract, through the same policy checks, with the same schema. There is no path where clicking a row does something the contract does not describe.
A plugin exposes a row by putting presentation metadata on the provision itself:
{
"name": "dev.example.notes.new.v1",
"title": "New note",
"audiences": ["plugin", "user"],
"palette": {
"category": "Notes",
"icon": "square.and.pencil",
"keywords": ["note", "capture"]
}
}palette.launcher: true puts a provision in ordinary launchers. palette.fillsPane: true marks an intent that can fill a pane handed to it in invocation scope — add it only when that is actually true.
Dynamic results
A static row is a fixed action. When the rows depend on what you typed — open a file, jump to a branch, pick a session — a plugin registers a provider instead, observes revisioned queries, and publishes results for that exact revision:
tenon.palette.registerProvider("files", { title: "Files" })
tenon.palette.onQuery("files", async (query) => {
const hits = await search(query.text)
tenon.palette.setResults("files", query.revision, hits.map(toResult))
})The revision is the point. Results are published for the query they answer, so a slow provider answering an old keystroke cannot overwrite the rows for the current one. Each result invokes an intent the plugin provides — again, not a second execution API.
Keybindings
A plugin can register a host-wide keybinding for an intent it owns. Those are discoverable and rebindable, and they sit alongside the built-in shortcuts.
A keyboard control that only works inside one focused view is that view's own business and is not registered as a product keybinding — the test is whether it is host-wide, discoverable, or rebindable outside the view that owns it.
See also
- Palette contributions — building rows and providers.
- Providing intents — the contract behind a row.
- All intents — everything the host itself provides.