Host services
Discover the APIs your Host actually provides, with parameter and result examples for everyday tasks.
Verified September 11, 2026
On this page
Discover your Host’s contracts#
Call host.services to inspect the running Host. Its response gives registered services and their actual parameter/result contracts, including differences between builds.
import { trove } from "@trove/plugin-sdk";
await trove.ready();
const available = await trove.call("host.services", "list", { prefix: "host." });
const storageContract = await trove.call("host.services", "describe", {
service: "host.storage",
});
console.log(available, storageContract);
| Method | Parameters | Result |
|---|---|---|
list | { prefix?: string } | { services: [{ id, version, provider }] } |
describe | { service: string, version?: string } | { descriptor, contract } |
resolve | { service: string, version?: string } | { id, version, provider } |
getStatus | { service: string, version?: string } | { id, version, state } |
A version range mismatch rejects with service.version_mismatch. Status is Declared, Starting, Available, or Unavailable; registration alone does not prove a Backend is running.
Runtime and paths#
| Method | Parameters | Result |
|---|---|---|
echo | Any JSON value | The same JSON value |
getHostInfo | {} | { name, version, platform, arch, protocol } |
getContext | {} | Current Curio identity and mode |
getPaths | {} | { data, cache, logs, temp }, each an absolute path |
openCurio | { id } | { ok: true } |
closeSelf | {} | { ok: true } |
revealPath | { path } | { ok: true } |
openUrl | { url } | { ok: true } |
The final four operations require the desktop Host. Use the returned paths rather than hard-coding a user’s home or application data directory. data is for persistent files, cache for regenerable content, and temp for session work.
Store small JSON values#
host.storage isolates keys by the Host-bound Curio ID. A single serialized value is limited to 1 MiB and the serialized store to 16 MiB. It is JSON storage, not a keychain.
| Method | Parameters | Result |
|---|---|---|
set | { key: string, value: JSON } | { stored: true } |
get | { key: string } | { value: JSON, found: boolean } |
delete | { key: string } | { deleted: boolean } |
list | { prefix?: string } | { keys: string[] } |
clear | {} | { cleared: true } |
const storage = trove.service("host.storage");
const key = `docs-demo-${crypto.randomUUID()}`;
try {
await storage.call("set", { key, value: { theme: "system" } });
const saved = await storage.call<{
found: boolean;
value: { theme: string } | null;
}>("get", { key });
console.log(saved.found, saved.value);
} finally {
await storage.call("delete", { key });
}
A missing key returns found: false, value: null. A stored JSON null returns found: true, value: null; check found before interpreting the value. Use the data directory for larger files.
Work with files#
host.fs.readText({ path }) returns { content: string }; writeText({ path, content }) returns { written: true }. Paths are filesystem paths, not browser URLs. Current text and binary transfers are limited to 4 MiB per file.
const { temp } = await trove.call<{ temp: string }>("host.runtime", "getPaths", {});
const path = `${temp}/docs-${crypto.randomUUID()}.txt`;
try {
await trove.call("host.fs", "writeText", { path, content: "Hello Trove" });
const file = await trove.call<{ content: string }>("host.fs", "readText", { path });
console.log(file.content);
} finally {
await trove.call("host.fs", "remove", { path });
}
| Method | Parameters | Result |
|---|---|---|
stat | { path } | { type, size, modifiedUnixMs } |
list | { path } | { entries: [{ name, path, type }] }; up to 20,000 entries |
exists | { path } | { exists: boolean } |
readBinary | { path } | { data: string }, Base64 encoded |
writeBinary | { path, data } | { written: true }; data is Base64 |
createDirectory | { path } | { created: true } |
copy / move | { from, to } | { copied: true } / { moved: true } |
remove | { path, recursive?: boolean } | { removed: true } |
createTempFile | {} | { path: string } |
Ask users to select their files through host.dialog when appropriate. Host filesystem calls do not imply the selected path is a Curio-only sandbox; respect the user’s intended file scope and macOS permissions.
Desktop integrations#
const clipboard = await trove.call<{ text: string }>("host.clipboard", "readText", {});
console.log(clipboard.text);
await trove.call("host.notification", "show", {
title: "Export complete",
body: "Your file is ready.",
});
Clipboard supports readText({}) → { text }, writeText({ text }) → { written: true }, and clear({}) → { cleared: true }. Notification currently supports only show({ title, body }) → { shown: true, curioId }.
Use describe to retrieve the full contract before integrating the following services:
| Service | Registered methods / topics |
|---|---|
host.window | show, hide, close, focus, getBounds, setBounds, center, setTitle, setAlwaysOnTop, setResizable, setDecorations, setIgnoreCursorEvents |
host.dialog | openFile, openDirectory, saveFile, message, confirm |
host.application | listInstalled, listRunning, launch, activate, terminate, open, getFrontmost |
host.shortcut | register, unregister, listSelf; triggered topic |
Implemented and planned capabilities#
| Capability | Current implementation |
|---|---|
| Runtime, discovery, storage, filesystem | Implemented |
| Windows, dialogs, text clipboard, notifications, applications, shortcuts | Implemented in desktop Host; inspect its contract |
host.clipboard.readFiles/writeFiles/getChangeCount | Draft only |
host.notification.remove/removeAllForCurio | Draft only |
host.fs.watch | Draft only |
host.process, host.accessibility, host.input, host.screen, host.keychain | Planned; not registered in the current build |
Do not infer method availability from a service name in an architecture draft. Handle service.not_found and service.method_not_found and check the installed Host version before enabling a feature.