API Reference
Complete schema reference for Hamr plugin development.
Manifest Schema
The manifest.json file defines your plugin's metadata and capabilities.
Required Fields
| Field |
Type |
Description |
name |
string |
Display name shown in launcher |
description |
string |
Short description |
icon |
string |
Material icon name |
supportedCompositors |
array |
["*"], ["hyprland"], ["niri"], or combination |
Optional Fields
| Field |
Type |
Default |
Description |
handler |
string |
"handler.py" |
Handler script filename |
frecency |
string |
"item" |
Usage tracking: "item", "plugin", or "none" |
indexOnly |
bool |
false |
Plugin only provides indexed items, no interactive mode |
Daemon Configuration
{
"daemon": {
"enabled": true,
"background": false
}
}
| Field |
Type |
Default |
Description |
daemon.enabled |
bool |
false |
Enable persistent daemon mode |
daemon.background |
bool |
false |
Run always (true) or only when plugin open (false) |
Index Configuration
{
"index": {
"enabled": true
}
}
| Field |
Type |
Default |
Description |
index.enabled |
bool |
false |
Enable main search integration (requires daemon) |
Pattern Matching Configuration
{
"match": {
"patterns": ["^=", "^[\\d\\.]+\\s*[\\+\\-]"],
"priority": 100
}
}
| Field |
Type |
Default |
Description |
match.patterns |
array |
- |
Regex patterns to trigger instant match |
match.priority |
number |
50 |
Higher priority wins when multiple plugins match |
Complete Manifest Example
{
"name": "My Plugin",
"description": "What it does",
"icon": "star",
"supportedCompositors": ["*"],
"handler": "handler.py",
"frecency": "item",
"daemon": {
"enabled": true,
"background": false
},
"index": {
"enabled": true
},
"match": {
"patterns": ["^pattern"],
"priority": 100
}
}
Request Schema
Every handler invocation receives a JSON object on stdin.
Common Fields
| Field |
Type |
Always Present |
Description |
step |
string |
Yes |
Request type (see below) |
query |
string |
Yes |
Current search bar text |
selected |
object |
No |
Selected item info |
action |
string |
No |
Action button ID |
context |
string |
No |
Plugin state from previous response |
session |
string |
Yes |
Unique session identifier |
Step Types
| Step |
When Triggered |
Key Fields |
initial |
Plugin opens |
- |
search |
User types (realtime) or presses Enter (submit) |
query |
action |
User selects item or clicks action |
selected, action |
match |
Pattern matched in main search |
query |
form |
Form submitted |
formData |
formSlider |
Live form slider changed |
fieldId, value |
poll |
Polling tick |
query |
index |
Index request |
mode, indexedIds |
Request Examples
Initial:
{ "step": "initial", "query": "", "session": "abc123" }
Search:
{ "step": "search", "query": "firefox", "session": "abc123" }
Action (item click):
{ "step": "action", "selected": { "id": "item-1" }, "session": "abc123" }
Action (action button click):
{
"step": "action",
"selected": { "id": "item-1" },
"action": "copy",
"session": "abc123"
}
Match:
{ "step": "match", "query": "2+2", "session": "abc123" }
Form:
{
"step": "form",
"formData": { "title": "Note", "content": "..." },
"context": "__add__",
"session": "abc123"
}
Index:
{ "step": "index", "mode": "full", "session": "abc123" }
Response Schema
Every response must be a single JSON object with a type field.
Response Types
| Type |
Purpose |
results |
Display list of items |
execute |
Run action and/or close |
match |
Return pattern match result |
card |
Display markdown content |
form |
Show input form |
imageBrowser |
Image grid browser |
gridBrowser |
Generic grid layout |
prompt |
Simple text prompt |
update |
Patch existing items |
index |
Provide searchable items |
status |
Update plugin status |
error |
Show error message |
noop |
No UI change |
Results Response
{
"type": "results",
"results": [],
"placeholder": "Search...",
"inputMode": "realtime",
"clearInput": false,
"context": "",
"notify": "",
"pluginActions": [],
"navigateForward": null,
"navigateBack": null,
"navigationDepth": null,
"status": {}
}
| Field |
Type |
Required |
Default |
Description |
type |
string |
Yes |
- |
Must be "results" |
results |
array |
Yes |
- |
Array of result items |
placeholder |
string |
No |
- |
Search bar hint text |
inputMode |
string |
No |
"realtime" |
"realtime" or "submit" |
clearInput |
bool |
No |
false |
Clear search bar text |
context |
string |
No |
- |
State persisted across calls |
notify |
string |
No |
- |
Show notification toast |
pluginActions |
array |
No |
[] |
Toolbar action buttons |
navigateForward |
bool |
No |
- |
Increment navigation depth |
navigateBack |
bool |
No |
- |
Decrement navigation depth |
navigationDepth |
int |
No |
- |
Set exact navigation depth |
status |
object |
No |
- |
Plugin status update |
Result Item Schema
{
"id": "unique-id",
"name": "Display Name",
"description": "Subtitle text",
"icon": "star",
"iconType": "material",
"thumbnail": "/path/to/image.png",
"verb": "Open",
"actions": [],
"badges": [],
"chips": [],
"graph": {},
"gauge": {},
"progress": {},
"preview": {}
}
| Field |
Type |
Required |
Default |
Description |
id |
string |
Yes |
- |
Unique identifier |
name |
string |
Yes |
- |
Primary display text |
description |
string |
No |
- |
Secondary text |
icon |
string |
No |
- |
Material icon name |
iconType |
string |
No |
"material" |
"material" or "system" |
thumbnail |
string |
No |
- |
Image path (overrides icon) |
verb |
string |
No |
- |
Action text on hover |
actions |
array |
No |
[] |
Secondary action buttons (max 4) |
badges |
array |
No |
[] |
Circular indicators (max 5) |
chips |
array |
No |
[] |
Pill-shaped tags |
graph |
object |
No |
- |
Line graph (replaces icon) |
gauge |
object |
No |
- |
Circular progress (replaces icon) |
progress |
object |
No |
- |
Progress bar (replaces description) |
preview |
object |
No |
- |
Side panel content |
Slider Item Schema
{
"id": "volume",
"type": "slider",
"name": "Volume",
"description": "",
"icon": "volume_up",
"value": 75,
"min": 0,
"max": 100,
"step": 5,
"unit": "%"
}
| Field |
Type |
Required |
Default |
Description |
id |
string |
Yes |
- |
Unique identifier |
type |
string |
Yes |
- |
Must be "slider" |
name |
string |
Yes |
- |
Label text |
description |
string |
No |
- |
Subtitle |
icon |
string |
No |
- |
Material icon |
value |
number |
Yes |
- |
Current value |
min |
number |
No |
0 |
Minimum value |
max |
number |
No |
100 |
Maximum value |
step |
number |
No |
1 |
Step increment |
unit |
string |
No |
- |
Unit suffix (e.g., "%") |
Switch Item Schema
{
"id": "mute",
"type": "switch",
"name": "Mute",
"description": "",
"icon": "volume_off",
"value": false
}
| Field |
Type |
Required |
Default |
Description |
id |
string |
Yes |
- |
Unique identifier |
type |
string |
Yes |
- |
Must be "switch" |
name |
string |
Yes |
- |
Label text |
description |
string |
No |
- |
Subtitle |
icon |
string |
No |
- |
Material icon |
value |
bool |
Yes |
- |
Current state |
{
"id": "copy",
"name": "Copy",
"icon": "content_copy",
"entryPoint": {}
}
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Action identifier |
name |
string |
Yes |
Button label/tooltip |
icon |
string |
No |
Material icon |
entryPoint |
object |
No |
For indexed items only |
Plugin Action Schema
{
"id": "add",
"name": "Add",
"icon": "add_circle",
"shortcut": "Ctrl+1",
"confirm": "Are you sure?",
"active": false
}
| Field |
Type |
Required |
Default |
Description |
id |
string |
Yes |
- |
Action identifier |
name |
string |
Yes |
- |
Button label |
icon |
string |
No |
- |
Material icon |
shortcut |
string |
No |
"Ctrl+N" |
Keyboard shortcut hint |
confirm |
string |
No |
- |
Confirmation dialog message |
active |
bool |
No |
false |
Highlight as active |
Badge Schema
{
"text": "5",
"icon": "star",
"image": "/path/to/avatar.png",
"color": "#ffffff"
}
| Field |
Type |
Required |
Description |
text |
string |
No |
1-3 character text |
icon |
string |
No |
Material icon (overrides text) |
image |
string |
No |
Image path (overrides text/icon) |
color |
string |
No |
Text/icon color |
Chip Schema
{
"text": "Label",
"icon": "tag",
"color": "#ffffff",
"background": "#4caf50"
}
| Field |
Type |
Required |
Description |
text |
string |
Yes |
Chip text |
icon |
string |
No |
Material icon |
color |
string |
No |
Text/icon color |
background |
string |
No |
Background color |
Graph Schema
{
"values": [10, 25, 15, 30, 20],
"color": "#4caf50",
"max": 100
}
| Field |
Type |
Required |
Default |
Description |
values |
array |
Yes |
- |
Array of numbers |
color |
string |
No |
theme |
Line color |
max |
number |
No |
auto |
Maximum Y value |
Gauge Schema
{
"value": 75,
"max": 100,
"label": "75%",
"color": "#4caf50"
}
| Field |
Type |
Required |
Default |
Description |
value |
number |
Yes |
- |
Current value |
max |
number |
No |
100 |
Maximum value |
label |
string |
No |
- |
Center label |
color |
string |
No |
theme |
Arc color |
Progress Schema
{
"value": 50,
"max": 100,
"label": "Downloading...",
"color": "#2196f3"
}
| Field |
Type |
Required |
Default |
Description |
value |
number |
Yes |
- |
Current value |
max |
number |
No |
100 |
Maximum value |
label |
string |
No |
- |
Text label |
color |
string |
No |
theme |
Bar color |
Preview Schema
{
"type": "markdown",
"content": "# Preview\n\nContent here...",
"detached": false
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
"markdown", "image", or "code" |
content |
string |
Yes |
Preview content |
detached |
bool |
No |
Show as floating panel |
language |
string |
No |
Code language (for "code" type) |
Execute Response
{
"type": "execute",
"launch": "/path/to/app.desktop",
"copy": "text to copy",
"typeText": "text to type",
"openUrl": "https://example.com",
"open": "/path/to/file",
"notify": "Done!",
"sound": "complete",
"close": true
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "execute" |
launch |
string |
No |
Desktop file path |
copy |
string |
No |
Text to copy to clipboard |
typeText |
string |
No |
Text to type via ydotool |
openUrl |
string |
No |
URL to open |
open |
string |
No |
File/folder path to open |
notify |
string |
No |
Notification message |
sound |
string |
No |
Sound effect name |
close |
bool |
No |
Close launcher |
Sound Names
| Sound |
Description |
alarm |
Timer/alarm completion |
timer |
Pomodoro, countdown |
complete |
Task done |
notification |
Alerts |
error |
Failed operations |
warning |
Caution alerts |
Match Response
{
"type": "match",
"result": {
"id": "calc_result",
"name": "4",
"description": "2+2",
"icon": "calculate",
"verb": "Copy",
"copy": "4",
"openUrl": "",
"notify": "Copied: 4",
"close": true,
"priority": 100,
"actions": []
}
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "match" |
result |
object/null |
Yes |
Match result or null to hide |
Match Result Fields
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Unique identifier |
name |
string |
Yes |
Primary text (the result) |
description |
string |
No |
Secondary text (the input) |
icon |
string |
No |
Material icon |
verb |
string |
No |
Action text |
copy |
string |
No |
Copy on selection |
openUrl |
string |
No |
Open URL on selection |
notify |
string |
No |
Notification after action |
close |
bool |
No |
Close launcher |
priority |
number |
No |
Ranking priority |
actions |
array |
No |
Secondary action buttons |
Card Response
{
"type": "card",
"card": {
"title": "Definition",
"content": "**noun**\n\nMeaning...",
"markdown": true,
"actions": []
},
"context": "word-id",
"inputMode": "submit",
"placeholder": "Type reply..."
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "card" |
card |
object |
Yes |
Card content |
context |
string |
No |
State for action handling |
inputMode |
string |
No |
"realtime" or "submit" |
placeholder |
string |
No |
Input hint |
Card Object Fields
| Field |
Type |
Required |
Description |
title |
string |
No |
Card title |
content |
string |
Yes |
Card content |
markdown |
bool |
No |
Render as markdown |
actions |
array |
No |
Action buttons |
{
"type": "form",
"form": {
"title": "Add Item",
"submitLabel": "Save",
"cancelLabel": "Cancel",
"liveUpdate": false,
"fields": []
},
"context": "__add__"
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "form" |
form |
object |
Yes |
Form definition |
context |
string |
No |
State passed to submission |
| Field |
Type |
Required |
Default |
Description |
title |
string |
No |
- |
Form title |
submitLabel |
string |
No |
"Submit" |
Submit button text |
cancelLabel |
string |
No |
"Cancel" |
Cancel button text |
liveUpdate |
bool |
No |
false |
Apply changes immediately |
fields |
array |
Yes |
- |
Form field definitions |
Text Field
{
"id": "name",
"type": "text",
"label": "Name",
"placeholder": "Enter name...",
"required": true,
"default": "",
"hint": "Helper text"
}
Textarea Field
{
"id": "content",
"type": "textarea",
"label": "Content",
"placeholder": "",
"required": false,
"default": "",
"rows": 6,
"hint": ""
}
Email Field
{
"id": "email",
"type": "email",
"label": "Email",
"placeholder": "user@example.com",
"required": true,
"default": "",
"hint": ""
}
Password Field
{
"id": "password",
"type": "password",
"label": "Password",
"placeholder": "",
"required": true,
"hint": ""
}
Hidden Field
{
"id": "item_id",
"type": "hidden",
"value": "abc123"
}
Select Field
{
"id": "theme",
"type": "select",
"label": "Theme",
"options": [
{ "id": "light", "name": "Light" },
{ "id": "dark", "name": "Dark" }
],
"default": "dark",
"hint": ""
}
Checkbox Field
{
"id": "agree",
"type": "checkbox",
"label": "I agree to terms",
"default": false,
"hint": ""
}
Switch Field
{
"id": "enabled",
"type": "switch",
"label": "Enabled",
"default": true,
"hint": ""
}
Slider Field
{
"id": "volume",
"type": "slider",
"label": "Volume",
"min": 0,
"max": 100,
"step": 5,
"unit": "%",
"default": 50,
"hint": ""
}
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Field identifier |
type |
string |
Yes |
Field type |
label |
string |
No |
Display label |
required |
bool |
No |
Validation |
default |
varies |
No |
Default value |
hint |
string |
No |
Helper text |
Image Browser Response
{
"type": "imageBrowser",
"imageBrowser": {
"directory": "~/Pictures",
"title": "Select Image",
"enableOcr": false,
"actions": []
}
}
| Field |
Type |
Required |
Description |
directory |
string |
Yes |
Directory to browse |
title |
string |
No |
Browser title |
enableOcr |
bool |
No |
Enable OCR text search |
actions |
array |
No |
Action buttons |
Grid Browser Response
{
"type": "gridBrowser",
"gridBrowser": {
"title": "Select Item",
"columns": 8,
"cellAspectRatio": 1.0,
"items": [],
"actions": []
}
}
| Field |
Type |
Required |
Default |
Description |
title |
string |
No |
- |
Browser title |
columns |
int |
No |
8 |
Number of columns |
cellAspectRatio |
float |
No |
1.0 |
Width/height ratio |
items |
array |
Yes |
- |
Grid items |
actions |
array |
No |
[] |
Action buttons |
Grid Item Schema
{
"id": "item-1",
"name": "Item Name",
"icon": "star",
"iconType": "material",
"keywords": ["search", "terms"]
}
Index Response
{
"type": "index",
"mode": "full",
"items": [],
"remove": []
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "index" |
mode |
string |
No |
"full" or "incremental" |
items |
array |
Yes |
Items to index |
remove |
array |
No |
Item IDs to remove (incremental) |
Index Item Schema
{
"id": "app:firefox",
"name": "Firefox",
"description": "Web Browser",
"icon": "firefox",
"iconType": "system",
"keywords": ["browser", "web"],
"verb": "Open",
"entryPoint": {
"step": "action",
"selected": { "id": "app:firefox" }
},
"actions": []
}
| Field |
Type |
Required |
Description |
id |
string |
Yes |
Unique identifier |
name |
string |
Yes |
Display name (searchable) |
description |
string |
No |
Subtitle |
icon |
string |
No |
Icon name |
iconType |
string |
No |
"material" or "system" |
keywords |
array |
No |
Additional search terms |
verb |
string |
No |
Action text |
entryPoint |
object |
Yes |
How to invoke handler |
actions |
array |
No |
Secondary actions |
Entry Point Schema
{
"step": "action",
"selected": { "id": "item-id" },
"action": "copy",
"query": ""
}
| Field |
Type |
Required |
Default |
Description |
step |
string |
No |
"action" |
Step type |
selected |
object |
No |
- |
Selected item info |
action |
string |
No |
- |
Action to perform |
query |
string |
No |
- |
Query string |
Status Response
{
"type": "status",
"status": {
"badges": [],
"chips": [],
"description": "5 pending tasks",
"fab": {},
"ambient": []
}
}
| Field |
Type |
Description |
badges |
array |
Badge indicators |
chips |
array |
Chip tags |
description |
string |
Override manifest description |
fab |
object |
FAB override (see below) |
ambient |
array |
Ambient items (see below) |
FAB Override Schema
{
"chips": [{ "text": "04:32", "icon": "timer" }],
"badges": [],
"priority": 10,
"showFab": true
}
| Field |
Type |
Description |
chips |
array |
Chip widgets |
badges |
array |
Badge widgets |
priority |
number |
Higher wins if multiple |
showFab |
bool |
Force FAB visible |
Ambient Item Schema
{
"id": "timer-1",
"name": "Focus Timer",
"description": "24:32 remaining",
"icon": "timer",
"actions": [{ "id": "pause", "icon": "pause", "name": "Pause" }],
"duration": 0
}
| Field |
Type |
Description |
id |
string |
Unique identifier |
name |
string |
Primary text |
description |
string |
Secondary text |
icon |
string |
Material icon |
actions |
array |
Action buttons |
duration |
number |
Auto-dismiss ms (0 = permanent) |
Update Response
{
"type": "update",
"items": [
{
"id": "volume",
"gauge": { "value": 75, "max": 100 }
}
]
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "update" |
items |
array |
Yes |
Partial item updates |
Error Response
{
"type": "error",
"message": "Failed to connect"
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "error" |
message |
string |
Yes |
Error message |
Noop Response
No UI change. Use for background operations or when UI already reflects the change (e.g., slider adjustments).
Prompt Response
{
"type": "prompt",
"prompt": {
"text": "Enter search term..."
}
}
| Field |
Type |
Required |
Description |
type |
string |
Yes |
Must be "prompt" |
prompt.text |
string |
Yes |
Prompt message |
Special IDs
| ID |
Context |
Meaning |
__back__ |
selected.id |
Back button/Escape pressed |
__plugin__ |
selected.id |
Plugin action clicked |
__form_cancel__ |
selected.id |
Form cancelled |
__empty__ |
selected.id |
Non-actionable placeholder |
__dismiss__ |
action |
Ambient item dismissed |