5.7k

Builtin Commands

The Native SDK provides built-in bridge commands for app command routing, window management, generic native views, layered WebViews, platform support queries, native dialogs, selected OS capabilities, and credential storage. These are controlled by the builtin_bridge policy in RuntimeOptions, separate from app-defined bridge handlers.

Command Routing

CommandRequired permissionDescription
native-sdk.command.invokecommandDispatch an Event.command into the app runtime from the calling WebView
native-sdk.command.listcommandList the manifest command catalog loaded into the runtime

Command routing is available through window.zero.commands.invoke(...) when js_window_api is true. The manifest command catalog is available through window.zero.commands.list(). When runtime permissions are configured, command helpers require the command permission; the legacy window permission is still accepted for compatibility. The runtime emits a CommandEvent with source = .bridge, the calling window_id, and the calling view label when the request comes from a named child WebView.

Native controls can also bind a command when created with runtime.createView(...) or window.zero.views.create(...). On macOS, Linux, and Windows system WebView builds, native button-style controls dispatch the command with the native window_id and the originating view label. Controls inside a toolbar report source = .toolbar; other native controls report source = .native_view.

Platform Support Commands

CommandRequired permissionDescription
native-sdk.platform.supportswindowReturn whether the current platform and web engine support a feature

Platform support queries are available through window.zero.platform.supports(...) when js_window_api is true. The command accepts feature names from PlatformFeature, including main_webview, child_webviews, native_views, native_control_commands, menus, tray, shortcuts, dialogs, clipboard_text, clipboard_rich_data, open_url, reveal_path, notifications, recent_documents, credentials, file_drops, app_activation_events, and gpu_surfaces. JavaScript callers can also use camelCase aliases such as mainWebView, nativeControlCommands, clipboardRichData, recentDocuments, fileDrops, appActivationEvents, and gpuSurfaces. The helper accepts either a string or a selector object with feature or name; raw bridge payloads may use the same fields. Use an explicit builtin_bridge policy when you want per-command origin lists.

Window commands

CommandRequired permissionDescription
native-sdk.window.listwindowList all open windows
native-sdk.window.createwindowCreate a new window
native-sdk.window.focuswindowFocus a window by ID
native-sdk.window.closewindowClose a window by ID

Window commands are available through window.zero.windows.* when js_window_api is true, but the runtime still checks the request origin and the window permission when permissions are configured. Use an explicit builtin_bridge policy when you want per-command origin lists.

View Commands

CommandRequired permissionDescription
native-sdk.view.createviewCreate a generic native view or WebView-backed view in the calling window
native-sdk.view.listviewList generic views and WebViews in the calling window
native-sdk.view.updateviewPatch frame, layer, visibility, enabled state, role, text, command, or WebView URL
native-sdk.view.setFrameviewMove or resize a view
native-sdk.view.setVisibleviewShow or hide a view
native-sdk.view.focusviewFocus a view when the backend supports native focus for that kind
native-sdk.view.focusNext / native-sdk.view.focusPreviousviewMove focus through visible, enabled native controls and WebView-backed views
native-sdk.view.closeviewClose a generic view or child WebView

View commands are available through window.zero.views.* when js_window_api is true. They use origin checks and the view permission when runtime permissions are configured; the legacy window permission is still accepted for compatibility. windowId must match the calling window when provided. The update(label, patch), focus(label), and close(label) helpers accept string labels for the calling window; pass selector objects when you need an explicit windowId. View responses include frame, layer, visibility, enabled, focus, role, accessibility label, text, command, cursor, and open state. GPU responses also include surface presentation fields, input latency budget fields, retained canvas frame counters, and retained widget counters. kind: "webview" routes through the WebView backend. The macOS, Linux, and Windows system-WebView backends support native toolbar, titlebar_accessory, sidebar, statusbar, split, stack, button, icon_button, list_item, checkbox, toggle, segmented_control, text_field, search_field, label, spacer, and progress_indicator views. The macOS system-WebView backend also supports gpu_surface; Chromium hosts and unsupported native kinds return explicit unsupported-backend errors until implemented.

WebView Commands

CommandRequired permissionDescription
native-sdk.webview.createwindowCreate a named WebView in a window
native-sdk.webview.listwindowList WebViews in the calling window
native-sdk.webview.setFramewindowMove or resize a WebView
native-sdk.webview.navigatewindowNavigate a WebView
native-sdk.webview.setZoomwindowSet page zoom from 0.25 to 5.0
native-sdk.webview.setLayerwindowChange native stack order
native-sdk.webview.closewindowClose a WebView

WebView commands are available through window.zero.webviews.* when js_window_api is true. They use the same origin and window permission checks as window commands. WebView URLs are also checked against security.navigation.allowed_origins. Backend-specific gaps reject with invalid_request and an actionable unsupported-backend message.

If windowId is omitted, the runtime uses the window that sent the bridge message. If provided, windowId must match that same calling window. Child WebViews are isolated by default and receive window.zero only when created with bridge: true. The startup WebView is always listed as main; that label is reserved and cannot be used for child WebView creation.

Dialog commands

CommandRequired permissionDescription
native-sdk.dialog.openFiledialogShow a file open dialog
native-sdk.dialog.saveFiledialogShow a file save dialog
native-sdk.dialog.showMessagedialogShow a message dialog

Dialog commands are always default-deny and require an explicit builtin_bridge policy.

OS Commands

CommandRequired permissionDescription
native-sdk.os.openUrlnetworkOpen an allowed http:// or https:// URL in the system browser
native-sdk.os.showNotificationnotificationsShow a native system notification with a title, optional subtitle, and optional body
native-sdk.os.revealPathfilesystemReveal a local file or folder path in the platform file manager
native-sdk.os.addRecentDocumentfilesystemAdd a local path to the platform recent documents list
native-sdk.os.clearRecentDocumentsfilesystemClear recent documents registered by the application where the platform supports it

OS commands are always default-deny and require an explicit builtin_bridge policy. native-sdk.os.openUrl also checks security.navigation.external_links; the URL must match the external link allowlist before the platform service is called. macOS, Linux, and Windows system WebView hosts implement openUrl, revealPath, notifications, and recent-document commands; macOS Chromium also implements the current OS command set. Other platform hosts return invalid_request with the standard unsupported-service message until implemented.

Credential Commands

CommandRequired permissionDescription
native-sdk.credentials.setcredentialsStore a secret by service and account
native-sdk.credentials.getcredentialsRead a secret by service and account, returning null when it is missing
native-sdk.credentials.deletecredentialsDelete a stored secret by service and account

Credential commands are always default-deny and require an explicit builtin_bridge policy. The macOS system WebView and macOS Chromium hosts store secrets in Keychain. The Linux system WebView host stores secrets through Secret Service/libsecret when available. The Windows system WebView host stores secrets in Credential Manager. Other platform hosts return invalid_request with the standard unsupported-service message until implemented.

Clipboard Commands

CommandRequired permissionDescription
native-sdk.clipboard.readTextclipboardRead text/plain from the system clipboard
native-sdk.clipboard.writeTextclipboardWrite text/plain to the system clipboard
native-sdk.clipboard.readclipboardRead clipboard data by MIME type and return { mimeType, data }
native-sdk.clipboard.writeclipboardWrite clipboard data by MIME type

Clipboard commands are always default-deny and require an explicit builtin_bridge policy. Supported clipboard hosts provide text/plain through the existing text clipboard path. macOS system WebView, macOS Chromium, Linux system WebView, and Windows system WebView also support text/html, text/rtf, and application/rtf.

Enabling builtin commands

const app_permissions = [_][]const u8{
    native_sdk.security.permission_command,
    native_sdk.security.permission_view,
    native_sdk.security.permission_dialog,
    native_sdk.security.permission_window,
    native_sdk.security.permission_network,
    native_sdk.security.permission_filesystem,
    native_sdk.security.permission_clipboard,
    native_sdk.security.permission_notifications,
    native_sdk.security.permission_credentials,
};

.security = .{
    .permissions = &app_permissions,
    .navigation = .{
        .allowed_origins = &.{ "zero://app" },
        .external_links = .{
            .action = .open_system_browser,
            .allowed_urls = &.{ "https://example.com/docs/*" },
        },
    },
},
.builtin_bridge = .{
    .enabled = true,
    .commands = &.{
        .{ .name = "native-sdk.window.list", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.command.invoke", .permissions = .{ "command" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.command.list", .permissions = .{ "command" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.platform.supports", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.window.create", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.create", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.list", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.update", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.setFrame", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.setVisible", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.focus", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.focusNext", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.focusPrevious", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.view.close", .permissions = .{ "view" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.webview.create", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.webview.list", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.webview.setFrame", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.webview.navigate", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.webview.setZoom", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.webview.setLayer", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.webview.close", .permissions = .{ "window" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.dialog.openFile", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.dialog.saveFile", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.dialog.showMessage", .permissions = .{ "dialog" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.os.openUrl", .permissions = .{ "network" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.os.showNotification", .permissions = .{ "notifications" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.os.revealPath", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.os.addRecentDocument", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.os.clearRecentDocuments", .permissions = .{ "filesystem" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.clipboard.readText", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.clipboard.writeText", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.clipboard.read", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.clipboard.write", .permissions = .{ "clipboard" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.credentials.set", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.credentials.get", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
        .{ .name = "native-sdk.credentials.delete", .permissions = .{ "credentials" }, .origins = .{ "zero://app" } },
    },
},

JavaScript usage

await window.zero.windows.create({
  label: "tools",
  title: "Tools",
  width: 420,
  height: 320,
});

const preview = await window.zero.webviews.create({
  label: "preview",
  url: "https://example.com",
  frame: { x: 24, y: 24, width: 480, height: 320 },
  layer: 10,
  bridge: false,
});

await preview.setZoom(1.25);
await preview.setLayer(20);
await preview.close();

const toolbar = await window.zero.views.create({
  label: "toolbar",
  kind: "toolbar",
  frame: { x: 0, y: 0, width: 720, height: 44 },
  role: "toolbar",
});

await window.zero.views.create({
  label: "refresh",
  kind: "button",
  parent: "toolbar",
  frame: { x: 12, y: 8, width: 96, height: 28 },
  accessibilityLabel: "Refresh workspace",
  text: "Refresh",
  command: "app.refresh",
});

await toolbar.setVisible(false);

await window.zero.commands.invoke("app.save");
const commands = await window.zero.commands.list();

const hasNativeViews = await window.zero.platform.supports("native_views");

const files = await window.zero.invoke("native-sdk.dialog.openFile", {
  title: "Select a file",
  allowMultiple: true,
});

const result = await window.zero.invoke("native-sdk.dialog.showMessage", {
  style: "warning",
  title: "Confirm",
  message: "Are you sure?",
  primaryButton: "Yes",
  secondaryButton: "No",
});

await window.zero.os.openUrl("https://example.com/docs/start");
await window.zero.os.showNotification({
  title: "Build finished",
  subtitle: "native-sdk",
  body: "All checks passed.",
});
await window.zero.os.revealPath("/Users/me/Downloads/report.pdf");
await window.zero.os.addRecentDocument("/Users/me/Downloads/report.pdf");
await window.zero.os.clearRecentDocuments();

await window.zero.clipboard.writeText("Copied from Native SDK");
const text = await window.zero.clipboard.readText();
await window.zero.clipboard.write({
  mimeType: "text/html",
  data: "<strong>Copied from Native SDK</strong>",
});
const html = await window.zero.clipboard.read({ mimeType: "text/html" });

await window.zero.credentials.set({
  service: "com.example.app",
  account: "current-user",
  secret: "session-token",
});
const token = await window.zero.credentials.get({
  service: "com.example.app",
  account: "current-user",
});
await window.zero.credentials.delete({
  service: "com.example.app",
  account: "current-user",
});

See also: Multiple WebViews for frame and layer semantics, Dialogs for the full dialog type reference, Capabilities for OS capability support, and Security for policy details.