hush Docs

Reference

For agents

How an AI agent or a script can read these docs, write a user's settings.json, and check it before the user saves it.

This page is for AI agents, scripts, and people who automate their setup. It says how to read the docs, and how to set up Hush for a user.

Read the docs

The reference tables (settings, keys, query words, menu items) are made from Hush's own source code when the site is built, so they match the version that runs.

What an agent can do

Hush has no public API. Its API accepts only a signed-in browser session, and it may change at any time. So an agent sets Hush up through the user:

  1. Write the user's settings as JSON (see below).
  2. Give it to the user, who pastes it into Settings → General → Edit settings.json and chooses Save, or imports it as a file in Settings → General → Settings file.

Hush checks the JSON and shows an error if something is wrong; nothing is saved then. Everything about sorting, pushes, views, sections, menus, and keys is in settings.json. The things that are not (appearance, push devices, feeds, a custom token) are listed in settings.json.

Write settings.json

  • Write only what differs from the defaults. Leave out every setting that you do not change.
  • Saving replaces all settings. Ask the user for their current settings.json first (they can copy it from the page), and change that. A file without their rules deletes their rules.
  • rules, views, dash.pr, dash.issue, and the menus are lists: write the whole list. dash and menus are groups: write only the keys that you change.
  • Leave "v" in menus as it is.
  • Every key, type, default, and limit is in settings.json. The conditions of rules and views are in Rules and the query language.

To make a settings file to import, put the settings in this wrapper:

{ "hush": 1, "exportedAt": "2026-09-28T09:00:00.000Z", "settings": { "botsAreFyi": true } }

Check it before the user saves it

Check these, or Hush refuses the file:

  • Every rule has when (an object) and then with at least one of category, push, or triage.
  • category is "action", "fyi", or "muted". triage: "snooze" has snoozeHours, a whole number from 1 to 720.
  • Conditions are only the keys in the conditions table, and no list or text is empty. Values of kind, reason, type, category, and state are the stored values ("fix_ci", "review_requested", "PullRequest"), not the query words (fix-ci, review-requested, pr).
  • View ids are 1 to 16 lower-case letters or digits, and unique; names are 1 to 40 characters; at most 12 views.
  • Section ids are 1 to 40 lower-case letters, digits, or dashes; queries are 1 to 256 characters; at most 20 sections for each tab.
  • Key names follow the key format; command ids are in the keybinds table.
  • quietHours.timeZone is an IANA time zone, and from and to are minutes (0 to 1439) that differ.

Recipes

“Only my repositories may need me.” Rules have no “not”, so keep what needs you in your repositories with a first rule, and make everything else FYI with a wide rule after it:

{
	"rules": [
		{
			"name": "My repos can need me",
			"when": { "repo": ["acme/web", "acme/api"], "category": ["action"] },
			"then": { "category": "action" }
		},
		{ "name": "Everything else is FYI", "when": {}, "then": { "category": "fyi" } }
	]
}

A thread that needs you in acme/web or acme/api matches the first rule and stays in Needs you. Every other thread matches the second rule. A saved view per project is another way: it adds a tab and hides nothing.

“Push me only when someone reviews my PRs.”

{
	"pushAction": false,
	"rules": [
		{
			"name": "Reviews on my PRs",
			"when": {
				"type": ["PullRequest"],
				"reason": ["author"],
				"kind": ["address_review", "merge"]
			},
			"then": { "push": true }
		}
	]
}

“Quiet at night and on weekends in Berlin.”

{ "quietHours": { "from": 1260, "to": 480, "weekends": true, "timeZone": "Europe/Berlin" } }

“Done on D, Mute on Shift+D, and no key for Snooze.”

{ "keys": { "inbox.done": ["d"], "inbox.mute": ["Shift+d"], "inbox.snooze": [] } }

“Show PRs in the acme org only, and skip the everyone team.”

{ "dash": { "scope": "org:acme archived:false", "excludedTeams": ["acme/everyone"] } }

Explain Hush to a user

When a user asks why a thread is in Needs you, the answer is in What needs you and the turn reasons. The thread's row also says it: its summary (“CI failed on your PR”), and “rule: …” if a rule sorted it.