Skip to content

manifest.json Reference

Every source adapter includes a manifest.json at the root of its folder. The manifest declares what the source is, how often it runs, and which preference fields the user fills in during setup. The Mac app reads the manifest to list the source in the directory, render its setup wizard, and schedule its syncs.

manifest.json
{
"id": "hacker-news",
"name": "Hacker News Upvotes",
"description": "Index stories you've upvoted on Hacker News.",
"version": "1.0.0",
"author": "matt",
"category": "reading",
"schedule": "every 6 hours",
"config": {
"username": { "label": "HN Username", "type": "text", "placeholder": "pg" }
},
"needs_browser": false,
"kind": "feed",
"transport": "http",
"document_semantics": "bookmark"
}
Typestring
RequiredYes
Pattern^[a-z0-9-]+$ (lowercase, digits, hyphens)

A stable identifier for the source type, unique within a catalog. Used as the source’s namespace in storage and as the folder name in the catalog repo.


Typestring
RequiredYes

Human-readable display name, shown in the Mac app and the source directory. Keep it short and descriptive — "Hacker News Upvotes", not "HN Upvoted Stories Indexer v2".


Typestring
RequiredNo

A one-line description shown in the directory listing. Describe what gets indexed, not how.


Typestring — emoji or URL
RequiredNo

A single emoji or an HTTPS URL to a square icon (PNG/SVG). Shown alongside the source name.


Typestring — semver
RequiredYes

The source-adapter version, following semver. The Mac app uses it for update detection — bump it on each meaningful change so added instances can be offered the update.


Typestring
RequiredNo

Who wrote the source adapter. Shown in the directory; useful for attribution in community catalogs.


Typestring
RequiredNo

A grouping for the directory. Conventional values: reading, social, finance, dev, media, local, research, utility.


Typestring
RequiredNo (default: on demand)

Human-readable sync cadence — "every 6 hours", "daily", "hourly", "on demand". The Mac app parses it into a timer. Scheduling, retry, and sleep/wake handling all live in the Mac app; the cloud does not schedule syncs.

"schedule": "daily"

A live-only source that exposes only query() (no batch sync) can set "schedule": null.


Typeobject
RequiredNo (default: {})

The preference fields shown in the source’s setup wizard. Each key becomes a property on ctx.config; each value describes the input.

"config": {
"username": { "label": "HN Username", "type": "text", "placeholder": "pg" },
"feeds": { "label": "Feed URLs", "type": "text[]" }
}

Each field descriptor accepts:

KeyTypeDescription
labelstringDisplay label in the setup UI.
typestringInput type — text, text[], url, url[], path, number, boolean.
placeholderstringOptional example text.

Typeobject
RequiredNo

Auth fields the source needs (for upstreams that require login). Like config, the keys name the fields — but the values are stored in the macOS Keychain, not in the cloud, and surfaced to the source adapter at sync time via ctx.credentials.

"auth": {
"api_key": { "label": "API Key", "type": "password" },
"cookie": { "label": "x.com session", "type": "browser_cookie:x.com" }
}

Auth field types: password, oauth:<provider> (e.g. oauth:google), browser_cookie:<domain>. The setup wizard renders the appropriate native prompt. Nothing here is sent to or stored by the cloud.


Typeboolean
RequiredNo (default: false)

Whether the source adapter requires a Playwright browser (via ctx.browser). true for upstreams with no API that need a logged-in session (social bookmarks); false for plain HTTP/feed sources.

needs_browser also decides where the source runs. A needs_browser: true source runs on the Trove Mac app (badged “Runs on your Mac”), which launches the headless browser session — a real browser is one of the things Trove’s cloud can’t provide. Plain HTTP/feed sources (needs_browser: false) are eligible to run in Trove’s cloud by default. See Where sync runs.


These optional fields classify the source for the directory and for how Trove treats its documents. They are denormalized hints — Trove can usually infer them, but declaring them keeps listings accurate and document handling explicit.

Typestring
RequiredNo

What kind of upstream this is. Conventional values: feed (RSS/Atom/JSON feed), account (a logged-in account’s content), files (local filesystem), api (a structured API). Drives directory grouping and setup hints.

"kind": "feed"
Typestring
RequiredNo

How the source adapter reaches the upstream: http (plain fetch), browser (Playwright session), or fs (local filesystem). Should agree with needs_browsertransport: "browser" implies needs_browser: true.

"transport": "http"
Typestring
RequiredNo

The default content type for documents this source produces, when not set per-document. Conventional values: text, transcript, highlight, bookmark. A document’s own contentType always wins; this is the fallback applied to documents that omit it.

"document_semantics": "bookmark"

Typeboolean
RequiredNo (default: false)

If true, the source adapter also exports a query(ctx) function for real-time requests answered on demand (live search, stock quotes) in addition to — or instead of — scheduled sync.


A no-auth feed source needs only a handful of fields:

manifest.json
{
"id": "my-blog",
"name": "My Blog",
"version": "1.0.0",
"schedule": "daily",
"config": {
"feedUrl": { "label": "Feed URL", "type": "url" }
},
"needs_browser": false
}