Host settings API
client.hostSettings reads and changes settings the connected device itself exposes — today, the host name and timezone of a Linux system managed by systemd. The provider defines the fields; your app presents them without knowing which operating system is underneath.
Availability
Reading needs the host.settings.read permission, applying needs host.settings.write, and both need a connected workspace whose provider offers the host.settings capability. A provider without remote settings simply reports the capability as absent.
Even with both permissions, individual fields can be read-only: the provider decides, and says why.
Interface
interface RemoteHostSetting {
binding: string;
id: string; // for example "linux.hostname"
label: string;
description: string;
value: string | null; // null when the provider could not read it
revision: string | null; // pass this back when applying
editor: "text" | "select";
choices: string[]; // options for a select editor
writable: boolean;
reason: string | null; // why it is read-only, when it is
}
interface AppHostSettingsAPI {
read(location: { binding: string }, signal?: AbortSignal): Promise<RemoteHostSetting[]>;
apply(setting: Pick<RemoteHostSetting, "binding" | "id" | "revision">, value: string, signal?: AbortSignal): Promise<RemoteHostSetting>;
}apply returns the setting as the provider re-read it afterwards, so the value you display is the one the host actually has — not the one you sent.
Examples
Read what the device offers and build an interface from it:
const env = await client.environment.get();
if (!env.binding || !env.capabilities.includes("host.settings")) return;
for (const setting of await client.hostSettings.read({ binding: env.binding })) {
addField({
label: setting.label,
help: setting.description,
value: setting.value ?? "",
kind: setting.editor, // "text" or "select"
options: setting.choices,
disabled: !setting.writable,
note: setting.writable ? undefined : setting.reason ?? undefined,
});
}Apply a change with the revision you read, and show the verified result:
const updated = await client.hostSettings.apply(
{ binding: setting.binding, id: setting.id, revision: setting.revision },
"europe/sofia",
);
show(`${updated.label} is now ${updated.value}`);Always confirm with the user before applying — these change the machine, not your app. Read the settings again after a failure: the message tells you when a refresh is required.
Errors
| Code | Message | Meaning |
|---|---|---|
invalid | Supply the accepted binding and documented setting parameters, including a revision for changes. | Missing revision or wrong shape. |
unavailable | Remote settings are unavailable on this connection. | The provider offers no settings. |
unavailable | No remote settings source in this workspace. | Nothing is bound to that role. |
closed | This setting belongs to a previous connection. Refresh settings after accepting the current connection. | Stale binding. |
busy | Wait for the previous settings operation to finish. | One read and one apply at a time. |
aborted | The settings operation ended after cancellation or a connection change. It may have been applied; refresh before retrying. | Genuinely uncertain — refresh, do not retry blindly. |
failed | The provider's message | For example a rejected value or a command failure. |
Provider messages are worth surfacing verbatim: they explain, for instance, that a change was not confirmed and the host may already have applied it.
Lifecycle and permissions
One read and one apply may be outstanding per window; the window stays busy until a write settles, so the desktop will not quit or disconnect in the middle of a change.
Settings are validated by the provider before anything runs on the host, and applying is verified by reading the value back. A revision mismatch means someone else changed the setting — refresh and review again rather than forcing your value.
This API is about the device. Your app's own preferences belong in storage, which needs no connection.
Related guides
- Remote host settings — the built-in interface and what Linux exposes.
- Events and environment API — noticing that the capability appeared.
- Providers and device detection — where these fields come from.
- App lifecycle and services — error codes and cleanup.