# settings.json

> Every Hush setting in one JSON file, what each one controls, its type and default, and how the file is checked and saved.

Source: https://hush-gh.com/docs/settings

All of your Hush settings are one JSON object. The settings pages edit parts of it; **settings.json** shows all of it, also the settings that no page shows. You can edit it by hand, export it to a file, import a file, or give it to an agent to write.

Open it in **Settings → General → Edit settings.json** ([app.hush-gh.com/settings/json](https://app.hush-gh.com/settings/json)).

## How it works

- **It has only your changes.** A setting that you did not change is not in the file; it uses its default. A new default in Hush then applies to you too.
- **Remove a key to go back to its default.**
- **Save replaces all your settings.** A setting that is not in the file goes back to its default. `⌘ S` / `Ctrl + S` saves.
- **Hush checks the whole file first.** If one value is wrong, it shows the error, such as `Rule 2: "then" needs category, push, or triage.`, and saves nothing. Unknown keys are errors too.
- **`dash` and `menus` are groups.** Write only the keys that you change: `{ "dash": { "staleDays": 5 } }` keeps the default sections. A list, such as `dash.pr` or `rules`, is always replaced as a whole.
- **Changes apply at once**, on every device. A change to `rules`, `botsAreFyi`, `teamReviewsAreAction`, or `reviewResolution` sorts your stored threads again.

A complete example:

```json settings
{
	"pushFyi": false,
	"quietHours": { "from": 1320, "to": 420, "weekends": true, "timeZone": "America/New_York" },
	"reviewResolution": "any_review",
	"teamReviewsAreAction": true,
	"rules": [
		{ "name": "Website is FYI", "when": { "repo": "acme/website" }, "then": { "category": "fyi" } },
		{ "name": "Mute renovate", "when": { "author": "renovate*" }, "then": { "category": "muted" } },
		{ "name": "Always push Alice", "when": { "by": "alice" }, "then": { "push": true } }
	],
	"views": [{ "id": "web", "name": "Web", "base": "inbox", "when": { "repo": "acme/web-*" } }],
	"dash": {
		"scope": "org:acme archived:false",
		"excludedTeams": ["acme/everyone"],
		"staleDays": 5
	},
	"keys": { "inbox.done": ["d"] }
}
```

### What is not in settings.json

These are not settings of your account, so they are not in the file:

- **This browser only:** the mode and theme, the start page, the tab title and icon counts, and notes that you chose “Don't show again” for.
- **Your data:** push devices, feeds, and what you did to threads and items (Done, Snooze, Mute, hidden and moved items).
- **Your GitHub access:** the custom token, if any.

## Settings file

**Settings → General → Settings file** exports your settings to a file, and imports a file. Use it to keep a copy, to move to another account, or to share your rules.

The file is your settings.json in a small wrapper:

```json
{
	"hush": 1,
	"exportedAt": "2026-09-28T09:00:00.000Z",
	"settings": { "rules": [{ "when": { "repo": "acme/website" }, "then": { "category": "fyi" } }] }
}
```

- `hush` is the file format version: `1`.
- `settings` has only the changes, the same as settings.json.
- **Import replaces all your settings**, like Save in settings.json. Hush asks first, and says how many rules and views the file has. Settings that Hush no longer has are left out.

## All settings

| Key | Type | Default | In the app |
| --- | --- | --- | --- |
| [`pushAction`](#pushaction) | boolean | `true` | Settings → Notifications |
| [`pushFyi`](#pushfyi) | boolean | `false` | Settings → Notifications |
| [`pushTurnChanges`](#pushturnchanges) | boolean | `true` | settings.json only |
| [`pushResolved`](#pushresolved) | boolean | `true` | settings.json only |
| [`quietHours`](#quiethours) | object or null | `null` | Settings → Notifications |
| [`peekMarksRead`](#peekmarksread) | boolean | `true` | settings.json only |
| [`reviewResolution`](#reviewresolution) | "strict" or "any_review" | `"strict"` | settings.json only |
| [`botsAreFyi`](#botsarefyi) | boolean | `true` | Settings → Inbox |
| [`teamReviewsAreAction`](#teamreviewsareaction) | boolean | `false` | Settings → Inbox |
| [`rules`](#rules) | array of rules | `[]` | Settings → Inbox |
| [`views`](#views) | array of views | `[]` | Settings → Inbox |
| [`dash.pr`](#dash-pr) | array of sections | (see below) | Settings → PRs & issues |
| [`dash.issue`](#dash-issue) | array of sections | (see below) | Settings → PRs & issues |
| [`dash.scope`](#dash-scope) | string | `"archived:false"` | Settings → PRs & issues |
| [`dash.excludedTeams`](#dash-excludedteams) | array of strings | `[]` | Settings → PRs & issues |
| [`dash.staleDays`](#dash-staledays) | whole number, 1 to 60 | `3` | settings.json only |
| [`dash.hideOthersDrafts`](#dash-hideothersdrafts) | boolean | `true` | settings.json only |
| [`dash.hideBots`](#dash-hidebots) | boolean | `true` | settings.json only |
| [`menus.inbox`](#menus-inbox) | array of menu item ids | (see below) | Settings → General |
| [`menus.dash`](#menus-dash) | array of menu item ids | (see below) | Settings → General |
| [`keys`](#keys) | object: command id → array of keys | `{}` | Settings → Keybinds |

## Every setting

### pushAction

**Type:** boolean · **Default:** `true` · **In the app:** Settings → Notifications

Push “Needs you” threads: review requests, failed CI on your PRs, replies.

When a thread arrives in **Needs you**, Hush sends a push to every device that has push on. A rule with `"push": false` stops the push for the threads it matches; with `"push": true` it sends one even when this is off.

### pushFyi

**Type:** boolean · **Default:** `false` · **In the app:** Settings → Notifications

Push FYI threads too. Usually noisy; a rule with "push" is often better.

Also push FYI threads. Most people leave this off and write a rule with `"push": true` for the few repositories or people they care about.

### pushTurnChanges

**Type:** boolean · **Default:** `true` · **In the app:** none (settings.json only)

Push when a thread becomes your turn with no new notification from GitHub, for example new commits after your review.

GitHub sends no notification for some changes that make a thread your turn: new commits after your review, CI that fails later, a snooze that ends. The inbox watcher looks at open threads every 15 minutes. When one of them becomes your turn, Hush moves it to Needs you and, with this on, pushes it.

### pushResolved

**Type:** boolean · **Default:** `true` · **In the app:** none (settings.json only)

Change an alert from the last day to a quiet “✓ You approved” (or “Done”, “CI passes now”…) when it is resolved, then close it.

When an alert from the last day is resolved (you approved, CI passes now, you marked it Done on another device), Hush replaces it with a quiet alert such as “✓ You approved”, which then closes itself. Off: the old alert stays until you close it.

### quietHours

**Type:** object or null · **Default:** `null` · **In the app:** Settings → Notifications

No pushes at these times: { "from": minutes after midnight, "to": minutes, "weekends": true or false, "timeZone": "Europe/London" }, or null for off.

No pushes at these times. The alerts still go in the alert history (the bell). When quiet hours end, one push lists what waited.

- `from` and `to`: minutes after midnight, 0 to 1439. `from` later than `to` crosses midnight (22:00 to 07:00 is `1320` to `420`). They must differ.
- `weekends`: `true` also makes all of Saturday and Sunday quiet.
- `timeZone`: an IANA time zone name, such as `"Europe/London"` or `"America/New_York"`.

```json settings
{ "quietHours": { "from": 1320, "to": 420, "weekends": true, "timeZone": "Europe/London" } }
```

### peekMarksRead

**Type:** boolean · **Default:** `true` · **In the app:** none (settings.json only)

A thread open in the peek for a moment is marked as read (also on GitHub).

A PR or issue that stays open in the peek for 1.5 seconds is marked as read, in Hush and on GitHub. Off: only **Read** (or opening it on GitHub) marks it.

### reviewResolution

**Type:** "strict" or "any_review" · **Default:** `"strict"` · **In the app:** none (settings.json only)

When a review request stops being your turn. "strict": when GitHub no longer asks you. "any_review": also when someone else approves or asks for changes.

When a review request stops being your turn.

- `"strict"`: when GitHub no longer asks you: you reviewed, or the request was removed.
- `"any_review"`: also when someone other than you and the author approves or requests changes after the newest push. Useful on teams where one review is enough.

This also applies to team review requests.

### botsAreFyi

**Type:** boolean · **Default:** `true` · **In the app:** Settings → Inbox

Activity by bots (dependabot, renovate, codecov…) is FYI.

PRs that bots open (dependabot, renovate…) are FYI, and they show in Other on the Pull requests tab, unless they ask for your review by name. Comments and mentions by bots do not count as replies. A bot is a login that ends in `[bot]`, or starts with dependabot, renovate, github-actions, or codecov.

### teamReviewsAreAction

**Type:** boolean · **Default:** `false` · **In the app:** Settings → Inbox

A review request to one of your teams is “Needs you”, not FYI.

A review request to a team you are in goes to **Needs you** (and is pushed). Off, it is FYI in the inbox, and it shows under “Your team's turn” on the Pull requests tab.

### rules

**Type:** array of rules · **Default:** `[]` · **In the app:** Settings → Inbox

Inbox rules, top to bottom; the first match wins. Each is { "name", "enabled", "when": conditions, "then": { "category", "push", "triage", "snoozeHours" } }.

Your inbox rules. Hush checks them from top to bottom, after its own defaults. The first enabled rule that matches a thread wins. A change to the rules sorts your stored threads again. See [Rules](https://hush-gh.com/docs/rules) for the editor, and [the query language](https://hush-gh.com/docs/query-language) for the conditions.

A rule:

- `name` (text, optional): shown on the thread as “rule: …”.
- `enabled` (boolean, optional): `false` turns the rule off. Missing means on.
- `when` (object): the conditions. All must match. `{}` matches every thread.
- `then` (object): what to do. It needs at least one of `category`, `push`, or `triage`.
  - `category`: `"action"` (Needs you), `"fyi"`, or `"muted"`.
  - `push`: `true` or `false`, in place of the push settings.
  - `triage`: `"done"` moves the thread to Done, `"snooze"` snoozes it for `snoozeHours` (a whole number from 1 to 720). Hush moves a thread only when it has new activity or when the rule starts to match, so a thread that you move back stays where you put it.

```json settings
{
  "rules": [
    { "name": "Docs repo is FYI", "when": { "repo": "acme/website" }, "then": { "category": "fyi" } },
    { "name": "Mute dependabot", "when": { "author": "dependabot*" }, "then": { "category": "muted" } },
    {
      "name": "Nightly CI can wait",
      "when": { "type": ["CheckSuite"], "repo": "acme/nightly" },
      "then": { "triage": "snooze", "snoozeHours": 12, "push": false }
    }
  ]
}
```

### views

**Type:** array of views · **Default:** `[]` · **In the app:** Settings → Inbox

Saved views: extra inbox tabs. Each is { "id", "name", "base", "when": conditions }.

Saved views: extra tabs after the built-in inbox tabs, in this order. Up to 12.

- `id`: 1 to 16 lower-case letters or digits. Unique. Feeds and links use it.
- `name`: up to 40 characters. The tab label.
- `base`: the list the view starts from: `"inbox"` (Needs you + FYI), `"action"` (Needs you), `"fyi"` (FYI), `"snoozed"` (Snoozed), `"done"` (Done).
- `when`: the same conditions as rules. `category` here is the thread's list now, after your rules.

```json settings
{
  "views": [
    { "id": "web", "name": "Web team", "base": "inbox", "when": { "repo": "acme/web-*" } },
    { "id": "ci", "name": "Broken CI", "base": "action", "when": { "kind": ["fix_ci"] } }
  ]
}
```

### dash.pr

**Type:** array of sections · **Default:** below · **In the app:** Settings → PRs & issues

Pull request sections: saved GitHub searches { "id", "name", "query", "enabled" }. @me is you; @team runs once per tracked team.

The sections of the Pull requests tab. Each is a saved GitHub search. Up to 20.

- `id`: 1 to 40 lower-case letters, digits, or dashes. Unique.
- `name`: up to 60 characters.
- `query`: a [GitHub search](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests), 1 to 256 characters. `@me` is you. `@team` runs the search once for each team you track.
- `enabled`: `false` hides the section and skips its search.

A change to `dash.pr` replaces the whole list. To add a section, write the defaults below and your new one.

The defaults:

| id | name | query | enabled |
| --- | --- | --- | --- |
| `review-me` | Review requested from you | `is:pr is:open user-review-requested:@me` | true |
| `review-team` | Team review requests | `is:pr is:open team-review-requested:@team` | true |
| `mine` | Your PRs | `is:pr is:open author:@me` | true |
| `reviewed` | You reviewed | `is:pr is:open reviewed-by:@me -author:@me` | true |
| `assigned` | Assigned to you | `is:pr is:open assignee:@me` | true |
| `mentioned` | Mentions you | `is:pr is:open mentions:@me` | true |
| `team-mentioned` | Mentions your teams | `is:pr is:open team:@team` | false |

### dash.issue

**Type:** array of sections · **Default:** below · **In the app:** Settings → PRs & issues

Issue sections, the same as dash.pr.

The sections of the Issues tab, the same as `dash.pr`. The defaults:

| id | name | query | enabled |
| --- | --- | --- | --- |
| `assigned` | Assigned to you | `is:issue is:open assignee:@me` | true |
| `mine` | You opened | `is:issue is:open author:@me` | true |
| `mentioned` | Mentions you | `is:issue is:open mentions:@me` | true |
| `commented` | You commented | `is:issue is:open commenter:@me -author:@me` | true |
| `team-mentioned` | Mentions your teams | `is:issue is:open team:@team` | false |

### dash.scope

**Type:** string · **Default:** `"archived:false"` · **In the app:** Settings → PRs & issues

Added to every search, for example "org:acme archived:false".

Added to the end of every section's search, up to 200 characters. Use it to keep the tabs to your work: `"org:acme archived:false"`, or `"-repo:acme/website"`.

### dash.excludedTeams

**Type:** array of strings · **Default:** `[]` · **In the app:** Settings → PRs & issues

"org/team" slugs that @team skips.

Teams that `@team` sections skip, as `"org/team"` slugs. Hush finds your teams on GitHub (again every 6 hours); turn off big ones, such as “everyone”, to cut noise. A section searches the first 15 teams at most, and one tab runs up to 40 searches.

```json settings
{ "dash": { "excludedTeams": ["acme/everyone", "acme/contractors"] } }
```

### dash.staleDays

**Type:** whole number, 1 to 60 · **Default:** `3` · **In the app:** none (settings.json only)

An item whose turn is older than this many days is marked stale (1 to 60).

An item whose turn started more than this many days ago is **stale**: it shows how long it waited (“waiting 5d”) in amber. Items in the Other group are never stale.

### dash.hideOthersDrafts

**Type:** boolean · **Default:** `true` · **In the app:** none (settings.json only)

Hide draft PRs that you did not open.

Leave out draft PRs that someone else opened. Your own drafts always show (in Other).

### dash.hideBots

**Type:** boolean · **Default:** `true` · **In the app:** none (settings.json only)

Hide PRs and issues that bots opened, unless your review is requested.

Leave out PRs and issues that bots opened, unless your review is requested from you by name.

### menus.inbox

**Type:** array of menu item ids · **Default:** below · **In the app:** Settings → General

The right-click and “⋯” menu of inbox threads: item ids in order; "sep" is a line.

The items of the right-click menu (and the “⋯” menu on phones) of inbox threads, in order. `"sep"` is a separator line. Items that you leave out are hidden. Items that do not apply to a thread, such as Done in the Done tab, are left out when the menu opens. See the item ids in [Menus](https://hush-gh.com/docs/appearance-and-menus#menu-items).

```json settings
{ "menus": { "inbox": ["peek", "main", "sep", "done", "snooze:tomorrow", "until:ci_pass", "mute", "sep", "copy"] } }
```

Hush adds `"v"` (the menu version) next to your menus. Leave it: it tells Hush which new items you have already seen.

The default:

```json
[
  "peek",
  "main",
  "github",
  "sep",
  "done",
  "snooze",
  "mute",
  "restore",
  "read",
  "copy",
  "rule",
  "sep",
  "select",
  "selectAll"
]
```

### menus.dash

**Type:** array of menu item ids · **Default:** below · **In the app:** Settings → General

The menu of PRs and issues, the same way.

The menu of pull requests and issues on the dashboards, the same way as `menus.inbox`.

The default:

```json
[
  "peek",
  "main",
  "github",
  "sep",
  "move",
  "undoMove",
  "hide",
  "copy",
  "sep",
  "select",
  "selectAll"
]
```

### keys

**Type:** object: command id → array of keys · **Default:** `{}` · **In the app:** Settings → Keybinds

Keyboard shortcuts you changed: { "command id": ["key", …] }, for example { "inbox.done": ["d"] }. [] turns a shortcut off. Keys: "j", "Shift+j", "Mod+k" (⌘ or Ctrl), "Enter", "Space", "?".

The keyboard shortcuts that you changed. For each [command id](https://hush-gh.com/docs/keybinds#all-shortcuts), the keys that replace its default keys, up to 4. `[]` turns the shortcut off. Commands that you do not list keep their defaults.

How to write a key:

- Letters are lower case. Shift is a modifier: `"Shift+j"`, not `"J"`.
- Modifiers come first, in the order `Mod`, `Alt`, `Shift`. `Mod` is ⌘ on a Mac and Ctrl on other computers.
- Named keys: `Enter`, `Escape`, `Space`, `Tab`, `Backspace`, `Delete`, the arrows (`ArrowUp`…), `Home`, `End`, `PageUp`, `PageDown`, `F1` to `F12`.
- Other characters are themselves, with no Shift: `"?"`, `"/"`, `"1"`.

```json settings
{ "keys": { "inbox.done": ["d", "e"], "inbox.mute": [], "palette": ["Mod+k", "Mod+p"] } }
```
