diff --git a/.github/workflows/desktop-macos-signing.yml b/.github/workflows/desktop-macos-signing.yml
index 7e75d275fe..c9954d94f0 100644
--- a/.github/workflows/desktop-macos-signing.yml
+++ b/.github/workflows/desktop-macos-signing.yml
@@ -96,13 +96,15 @@ jobs:
# What a release signs and attaches: a candidate pinned to its own images with no updater,
# a stable release made Latest only once its signed Mac and Windows installers are both on
# it, every signed installer under its fixed download name too, and downloads.copilotkit.ai
- # serving only the Latest stable release's signed installers.
+ # serving only the Latest stable release's signed installers. And every signed build carries
+ # the Intelligence CLI, its Mac binaries signed for notarization: an app without it cannot set
+ # up Intelligence, and the updater would put it on every Mac.
- name: Signed release regressions
run: >-
bun test scripts/signed-build.test.ts scripts/publish-signed-mac.test.ts
scripts/publish-signed-windows.test.ts scripts/signing-workflows.test.ts
../scripts/release-latest.test.ts ../scripts/release-download-names.test.ts
- ../scripts/downloads-sync.test.ts
+ ../scripts/downloads-sync.test.ts scripts/release-cli-bundle.test.ts
working-directory: desktop
- name: Importing the Developer ID intermediate twice succeeds
# The first real signing run stopped here: the .p12 already carried the intermediate, and a
@@ -351,6 +353,9 @@ jobs:
echo '::error::The app is ad-hoc signed.'
exit 1
fi
+
+ # The CLI is in the app, and every Mach-O in it is ours, hardened and timestamped.
+ desktop/scripts/verify-cli-bundle.sh "$app" developer-id
# Named by architecture because both runners produce `OpenBot.app.tar.gz`, and latest.json
# points at one URL per platform. A pinned build made no updater archive.
- name: Collect the artifacts
diff --git a/.github/workflows/desktop-signing.yml b/.github/workflows/desktop-signing.yml
index 05cd822a29..162a3dc3b5 100644
--- a/.github/workflows/desktop-signing.yml
+++ b/.github/workflows/desktop-signing.yml
@@ -181,6 +181,15 @@ jobs:
if ($installers.Count -ne 1) { throw 'Expected exactly one NSIS installer.' }
& 7z e $installers[0].FullName '-odesktop/signed-app' '-r' '-y' 'openbot-desktop.exe'
if ($LASTEXITCODE -ne 0) { throw 'Could not extract signed app from NSIS installer.' }
+ # The CLI is in what people install, not only in the build folder.
+ - name: Verify the installer carries the Intelligence CLI
+ run: |
+ $installers = @(Get-ChildItem 'desktop/src-tauri/target/release/bundle/nsis/*-setup.exe' -File)
+ $listing = & 7z l $installers[0].FullName
+ if ($LASTEXITCODE -ne 0) { throw 'Could not list the NSIS installer.' }
+ foreach ($file in @('cli-bundle\runtime\node.exe', 'cli-bundle\cli\index.js')) {
+ if (-not ($listing | Select-String -SimpleMatch $file)) { throw "The installer has no $file." }
+ }
- name: Verify publisher, trust, and timestamp on both executables
run: |
$build = Get-Content desktop/build-version.json -Raw | ConvertFrom-Json
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1d36951ecd..992de1a74b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,25 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged.
## Unreleased
+- OpenBot Desktop now runs OpenBot for one person on one computer with CopilotKit Intelligence on
+ the same computer, set up from the app alone: Account, Install, AI, Start. The Intelligence CLI
+ and its Node runtime ship inside the app, pinned by SHA-256. **Before upgrading:** the Desktop app
+ no longer connects to a hosted or self-hosted Intelligence, has no organization sign-in and no
+ Bot picker. An installation an earlier app connected to a hosted Intelligence starts at the first
+ screen and keeps its finished install, its database and its Bots; its conversations stay in that
+ hosted Intelligence.
+- OpenBot Desktop runs every new installation as Compose project `openbot-desktop`, never a source
+ checkout's. An installation an earlier app made keeps its own project, and with it its database
+ and its Bots' computers, even when Stop or Quit took its containers down. If another OpenBot on
+ the computer, such as a source checkout called `openbot`, is running that project, Install says so
+ and waits for it to stop rather than starting with an empty database. Nothing is deleted either
+ way.
+- Settings → This computer, inside OpenBot Desktop, shows what runs, the memory each part takes, and
+ Restart and Stop for OpenBot and the local Intelligence. Only OpenBot's own page gets those
+ controls: a page on another port of this computer that opens in the window gets none of them.
+- The Windows installer and uninstaller stop the bundled CLI's background service before they
+ replace or remove it, including when the installation folder has an apostrophe in its name.
+- The Helm chart now installs CopilotKit Intelligence with OpenBot by default, so one `helm install` is the whole product: Intelligence 0.16.0-rc.2 in self-hosted mode on its own bundled PostgreSQL and Redis, with every credential it needs generated and kept across upgrades, OpenBot's project and runtime key created inside it by Intelligence's own bootstrap from a key the chart generates, with nobody signing in, and Automatic Learning and Trajectories on. The licence is given once, as `secrets.licenseToken`, and reaches both; Learning's agent runs on `secrets.modelApiKey`. The server carries the browser's socket to Intelligence's gateway on its own address, so a single `kubectl port-forward` reaches everything. The chart README's vanilla install is the three steps. **Before upgrading:** a release pointed at managed Intelligence, or at one of its own, needs `--set intelligence.enabled=false`; the chart refuses the upgrade until it is set rather than install a second, empty Intelligence.
- The desktop installers are served from `downloads.copilotkit.ai`, the address the website links
to. `https://downloads.copilotkit.ai/latest/OpenBot-mac-arm64.dmg`, `OpenBot-mac-x64.dmg` and
`OpenBot-windows-x64-setup.exe` give the signed installers of the Latest stable release, never a
@@ -98,10 +117,12 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged.
its last message, now also as plain text. A name the model writes in Markdown is stored as plain
text, and an answer too long to be a name is not stored as one. Migration `0077_channel_opening`
adds `channels.opening`.
-- The sign-in page the Desktop app opens now explains OpenBot setup — you are setting up a
- CopilotKit account for the personal edition of OpenBot, and your data stays on your computer —
- instead of the generic CopilotKit pitch. The app adds `mode=openbot` to the sign-in URL it opens;
- sign-in itself is unchanged, and an older hosted page ignores the mode.
+- The sign-in page the Desktop app opens explains OpenBot setup (you are setting up a CopilotKit
+ account for the personal edition of OpenBot, and your data stays on your computer) instead of the
+ generic CopilotKit pitch. The app signs in through the bundled Intelligence CLI and asks it for
+ that page with `copilotkit login --mode openbot` whenever the CLI's own `login --help` lists the
+ flag. A CLI from before the flag signs you in exactly as before, with the generic page. Sign-in
+ itself is unchanged either way.
- Choosing Anthropic in the Desktop setup screen, or setting `BOT_PROVIDER=anthropic` without a `BOT_MODEL`, now runs `claude-sonnet-5-5` instead of `claude-sonnet-4-5`, which Anthropic retires on 2026-11-30. A deployment that pins `BOT_MODEL` is unaffected.
- Code and markdown in a Bot's interface are drawn the way a reply draws them: highlighted in the light and dark themes, with the same copy and download buttons, tables and Doc links. They were plain monospace before, and nearly unreadable in dark mode.
- The Computer panel's Activity lists every command the Bot runs and every file it reads, saves or lists, with what it printed, whether the step ran at once, after you allowed it, or before the page was opened. It had stayed empty for anything that went through approval. A step that was not done shows why in your words ("You declined it."), not the sentence the Bot is told, and the line in the conversation says the same. A command you decline on the Bot's own approval card is listed too. A step you did yourself shows as done by you. A step shows the time it ran only when the page saw it run, never the time the page was opened. Resetting a computer from Admin clears the Activity of every Bot that ran on it, and a reload or another tab no longer brings it back.
diff --git a/app/src/components/layout/sidebar-shell.tsx b/app/src/components/layout/sidebar-shell.tsx
index e96b7399c6..f8c0fa227f 100644
--- a/app/src/components/layout/sidebar-shell.tsx
+++ b/app/src/components/layout/sidebar-shell.tsx
@@ -1,10 +1,21 @@
-import { type CSSProperties, type ReactNode, useEffect, useState } from "react";
+import {
+ type CSSProperties,
+ type ReactNode,
+ useEffect,
+ useMemo,
+ useState,
+} from "react";
-import { SidebarProvider } from "@/components/ui/sidebar";
+import {
+ SidebarProvider,
+ SidebarResizeProvider,
+} from "@/components/ui/sidebar";
import {
applySidebarOpen,
parseStoredSidebarOpen,
+ parseStoredSidebarWidth,
SIDEBAR_STORAGE_KEY,
+ SIDEBAR_WIDTH_STORAGE_PREFIX,
} from "@/lib/sidebar";
import { cn } from "@/lib/utils";
@@ -23,22 +34,46 @@ const SIDEBAR_GUTTER = "[&_[data-sidebar=menu-button]]:px-2.5";
* `defaultOpen` to true). Driving it as controlled state is a dozen lines, and three copies of a
* dozen lines is three chances for one shell to forget the preference the other two remember.
*
- * `width` is what actually differs between the shells. The app's roster earns 340px because its
- * rows are two-line message previews; admin and settings hold short nav labels and earn 300px.
+ * `width` is what differs between the shells before anybody resizes one. The app's roster earns
+ * 340px because its rows are two-line message previews; admin and settings hold short nav labels and
+ * earn 300px. Dragging the sidebar's edge (`SidebarRail`) changes it, and each shell remembers its
+ * own under its `name`.
*/
export function SidebarShell({
children,
className,
- width,
+ name,
+ width: defaultWidth,
}: {
children: ReactNode;
className?: string;
+ /** Whose width this is: each shell remembers its own, under this name. */
+ name: string;
+ /** The width before anybody drags the sidebar's edge. */
width: string;
}) {
// Read before the first paint, so a shell somebody left collapsed never flashes open.
const [open, setOpen] = useState(() =>
parseStoredSidebarOpen(window.localStorage.getItem(SIDEBAR_STORAGE_KEY)),
);
+ const widthKey = `${SIDEBAR_WIDTH_STORAGE_PREFIX}${name}`;
+ const [width, setWidth] = useState(() =>
+ parseStoredSidebarWidth(
+ window.localStorage.getItem(widthKey),
+ defaultWidth,
+ ),
+ );
+ // While the edge is dragged, the sidebar follows the pointer instead of easing after it.
+ const [resizing, setResizing] = useState(false);
+ const resize = useMemo(
+ () => ({
+ setWidth: (pixels: number) => setWidth(`${pixels}px`),
+ commitWidth: (pixels: number) =>
+ window.localStorage.setItem(widthKey, String(pixels)),
+ setResizing,
+ }),
+ [widthKey],
+ );
useEffect(() => {
applySidebarOpen(open, {
@@ -49,6 +84,7 @@ export function SidebarShell({
return (
- {children}
+ {children}
);
}
diff --git a/app/src/components/settings/settings-sidebar.tsx b/app/src/components/settings/settings-sidebar.tsx
index f237309b36..fa04873603 100644
--- a/app/src/components/settings/settings-sidebar.tsx
+++ b/app/src/components/settings/settings-sidebar.tsx
@@ -27,6 +27,7 @@ import {
SidebarMenuItem,
SidebarRail,
} from "@/components/ui/sidebar";
+import { desktopShell } from "@/lib/desktop/shell";
import { currentUserQueryOptions } from "@/lib/auth/queries";
import { deploymentCapabilitiesQueryOptions } from "@/lib/deployment/queries";
import { mayOpenSetup, setupChecklistQueryOptions } from "@/lib/setup/queries";
@@ -41,6 +42,8 @@ type SettingsSidebarItem = {
* everywhere else, so an entry stays lit on the pages beneath it.
*/
exact?: boolean;
+ /** Shown only inside OpenBot Desktop, which is what the page reads from. */
+ desktopOnly?: boolean;
icon: React.ComponentType<{ className?: string }>;
linkOptions: LinkOptions;
title: string;
@@ -92,6 +95,13 @@ export const SETTINGS_SIDEBAR_ITEMS: SettingsSidebarItem[] = [
icon: IconKey,
linkOptions: { to: "/settings/passwords" },
},
+ {
+ /* What OpenBot runs here and the memory it takes, with Restart and Stop. */
+ title: "This computer",
+ icon: IconDeviceDesktop,
+ desktopOnly: true,
+ linkOptions: { to: "/settings/this-computer" },
+ },
{
/* The same mark Admin gives UI Components. It is the same subject seen from the other side. */
title: "Components gallery",
@@ -195,7 +205,11 @@ export function SettingsSidebar({
{items
- .filter((option) => !option.setup || canSetUp)
+ .filter(
+ (option) =>
+ (!option.setup || canSetUp) &&
+ (!option.desktopOnly || desktopShell() !== null),
+ )
.map((option) => (
void;
+ commitWidth: (pixels: number) => void;
+ setResizing: (resizing: boolean) => void;
+};
+
+const SidebarResizeContext = React.createContext(null);
+
+const SidebarResizeProvider = SidebarResizeContext.Provider;
+
+/**
+ * The narrowest the sidebar can be and still show its footer whole: its widest footer button's own
+ * content, plus the paddings around it. Measured from what is drawn, never from a rem constant, and
+ * never under `SIDEBAR_MIN_WIDTH`. A sidebar with no footer has only that floor.
+ */
+function footerWidth(panel: HTMLElement): number {
+ const footer = panel.querySelector(
+ '[data-slot="sidebar-footer"]',
+ );
+ if (!footer) return SIDEBAR_MIN_WIDTH;
+ const around =
+ panel.getBoundingClientRect().width - footer.getBoundingClientRect().width;
+ const footerStyle = getComputedStyle(footer);
+ const footerPadding =
+ Number.parseFloat(footerStyle.paddingLeft) +
+ Number.parseFloat(footerStyle.paddingRight);
+ let widest = 0;
+ for (const button of footer.querySelectorAll(
+ '[data-sidebar="menu-button"]',
+ )) {
+ const style = getComputedStyle(button);
+ const gap = Number.parseFloat(style.columnGap) || 0;
+ const children = Array.from(button.children) as HTMLElement[];
+ // `scrollWidth`, not the drawn width: a truncated label still reports what it needs.
+ const content =
+ children.reduce((sum, child) => sum + child.scrollWidth, 0) +
+ gap * Math.max(0, children.length - 1);
+ widest = Math.max(
+ widest,
+ content +
+ Number.parseFloat(style.paddingLeft) +
+ Number.parseFloat(style.paddingRight),
+ );
+ }
+ return Math.max(
+ SIDEBAR_MIN_WIDTH,
+ Math.ceil(widest + footerPadding + around),
+ );
+}
+
+/**
+ * The sidebar's edge. Dragged, it resizes the sidebar between what its footer needs and the shell's
+ * maximum; clicked without moving, it hides or shows the sidebar as it always did. A press counts as
+ * a drag once it has moved 3px, so a click with a slight wobble still toggles.
+ */
function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
- const { toggleSidebar } = useSidebar();
+ const { toggleSidebar, state, isMobile } = useSidebar();
+ const resize = React.useContext(SidebarResizeContext);
+ const drag = React.useRef<{
+ startX: number;
+ startWidth: number;
+ min: number;
+ width: number;
+ moved: boolean;
+ } | null>(null);
+ const dragged = React.useRef(false);
return (
+ }
+ title="Details"
+ >
+
+
+
+
+
+
+
+ {status.engine === "podman" ? "Podman" : "Docker"}
+
+
+
+
+ {status.engine ? "Running" : "Not running"}
+
+
+
+
+
+
+
+
+
+ Installed in
+
+ {status.root}
+
+
+
+
+
+
+
+
+
+ Version {status.version}
+
+ {status.build}
+
+
+
+
+
+ );
+}
+
+/** Each container or process as a read-only row: its name, and its memory as the value. */
+function PartRows({
+ icon: Icon,
+ parts,
+ separatorFirst = false,
+}: {
+ icon: React.ComponentType<{ className?: string }>;
+ parts: DesktopPart[];
+ separatorFirst?: boolean;
+}) {
+ return parts.map((part, index) => (
+
+ {(separatorFirst || index > 0) && }
+
+
+
+
+
+ {part.name}
+
+
+
+ {part.memoryBytes === null ? "—" : formatBytes(part.memoryBytes)}
+
+
+
+
+ ));
+}
diff --git a/app/src/styles.css b/app/src/styles.css
index 62f38b13f8..ab08ef6773 100644
--- a/app/src/styles.css
+++ b/app/src/styles.css
@@ -16,6 +16,34 @@
/* Its code plugin, which Streamdown's docs say to scan the same way. */
@source "../node_modules/@streamdown/code/dist/*.js";
+/*
+ * OpenBot Desktop on macOS has no separate title bar over this page: the window's buttons sit over
+ * the top-left corner and the sidebar runs to the top edge, as in Mac apps with a sidebar. The
+ * desktop marks the page (`data-desktop-titlebar`) and makes the sidebar's header the drag handle;
+ * here the header makes room for the buttons above its own row. With the sidebar collapsed the
+ * buttons are over the main column instead, so that moves down. The main column is the shell's own
+ * ``; the primitive's `SidebarInset`, which an earlier rule aimed at, is used by no shell.
+ * Outside the desktop nothing changes.
+ */
+:root[data-desktop-titlebar="overlay"] [data-slot="sidebar-header"] {
+ height: auto;
+ padding-top: 36px;
+}
+
+:root[data-desktop-titlebar="overlay"]
+ [data-slot="sidebar-wrapper"]:has(
+ > [data-slot="sidebar"][data-state="collapsed"]
+ )
+ > main {
+ padding-top: 28px;
+}
+
+/* While the sidebar's edge is dragged, it follows the pointer rather than easing after it. */
+[data-slot="sidebar-wrapper"][data-resizing] [data-slot="sidebar-container"],
+[data-slot="sidebar-wrapper"][data-resizing] [data-slot="sidebar-gap"] {
+ transition: none;
+}
+
/*
* A tool line that is still running.
*
diff --git a/desktop/bun.lock b/desktop/bun.lock
index 94535e0f4c..2b2191e2cf 100644
--- a/desktop/bun.lock
+++ b/desktop/bun.lock
@@ -5,6 +5,7 @@
"": {
"name": "openbot-desktop",
"dependencies": {
+ "@fontsource-variable/inter": "5.3.0",
"@tauri-apps/api": "^2.12.4",
"@tauri-apps/plugin-process": "^2.4.0",
"@tauri-apps/plugin-updater": "^2.14.1",
@@ -118,6 +119,8 @@
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g=="],
+ "@fontsource-variable/inter": ["@fontsource-variable/inter@5.3.0", "", {}, "sha512-OupL48va4JNofb97w6NYeF9S7W/kHNKM0Er8Dem5nqi4jeOLrVJDoE8tZEpnMJmtkvNbB1EIPPwHcdkF6b1oUA=="],
+
"@happy-dom/global-registrator": ["@happy-dom/global-registrator@20.14.0", "", { "dependencies": { "@types/node": ">=20.0.0", "happy-dom": "^20.14.0" } }, "sha512-Xn0kdkaA1eHOaFFopr+YQ37sPNTZ3JScpUMz3j4rIsn1Nneqoh94z79iW23Ej0Ytt99+LlFr4JrSDd6ow9c7MQ=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
diff --git a/desktop/package.json b/desktop/package.json
index a289b1131e..af7d3feafe 100644
--- a/desktop/package.json
+++ b/desktop/package.json
@@ -9,6 +9,7 @@
"tauri": "tauri"
},
"dependencies": {
+ "@fontsource-variable/inter": "5.3.0",
"@tauri-apps/api": "^2.12.4",
"@tauri-apps/plugin-process": "^2.4.0",
"@tauri-apps/plugin-updater": "^2.14.1",
diff --git a/desktop/public/copilotkit-logo-dark.svg b/desktop/public/copilotkit-logo-dark.svg
new file mode 100644
index 0000000000..197202662f
--- /dev/null
+++ b/desktop/public/copilotkit-logo-dark.svg
@@ -0,0 +1,48 @@
+
diff --git a/desktop/public/copilotkit-logo.svg b/desktop/public/copilotkit-logo.svg
new file mode 100644
index 0000000000..e349b8a745
--- /dev/null
+++ b/desktop/public/copilotkit-logo.svg
@@ -0,0 +1,48 @@
+
+ CopilotKit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CopilotKit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/desktop/scripts/cli-bundle.test.ts b/desktop/scripts/cli-bundle.test.ts
index f6fa30b06a..336bd9f38e 100644
--- a/desktop/scripts/cli-bundle.test.ts
+++ b/desktop/scripts/cli-bundle.test.ts
@@ -11,7 +11,7 @@ import {
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
-import { join } from "node:path";
+import { join, resolve } from "node:path";
import {
bundleCli,
downloadNode,
@@ -304,7 +304,7 @@ function fakePackRun(pkg: {
return { code: 0, stdout: out, stderr: "" };
}
if (cmd[0] === "tar") {
- const dir = join(cmd[cmd.indexOf("-C") + 1], "package");
+ const dir = join(resolve(cwd, cmd[cmd.indexOf("-C") + 1]), "package");
mkdirSync(dir, { recursive: true });
writeFileSync(
join(dir, "package.json"),
@@ -342,6 +342,25 @@ function packDirs() {
return { workDir: join(root, "work"), cliDir: join(root, "cli") };
}
+/**
+ * Windows: the build step runs in Git's bash, whose GNU tar reads `D:\\a\\...\\copilotkit.tgz` as the
+ * host `D` and fails ("Cannot connect to D: resolve failed"). The tarball is named relative to the
+ * work folder it is unpacked in, which every tar reads as a file.
+ */
+test("unpacks the CLI by paths relative to its work folder", () => {
+ const { workDir, cliDir } = packDirs();
+ mkdirSync(workDir, { recursive: true });
+ const { run, calls } = fakePackRun({
+ name: "copilotkit",
+ version: "4.33.1",
+ bin: { copilotkit: "index.js" },
+ });
+ packCli({ kind: "npm", spec: "copilotkit@latest" }, workDir, cliDir, run);
+ const tar = calls.find((call) => call.cmd[0] === "tar");
+ expect(tar?.cmd).toEqual(["tar", "-xzf", "copilotkit-4.33.1.tgz", "-C", "."]);
+ expect(tar?.cwd).toBe(workDir);
+});
+
test("packs a preview and reports the package's own name and version", () => {
const { workDir, cliDir } = packDirs();
mkdirSync(workDir, { recursive: true });
diff --git a/desktop/scripts/cli-bundle.ts b/desktop/scripts/cli-bundle.ts
index f59a32ff12..5cd4591c82 100644
--- a/desktop/scripts/cli-bundle.ts
+++ b/desktop/scripts/cli-bundle.ts
@@ -230,7 +230,9 @@ export function packCli(
runChecked(
run,
- ["tar", "-xzf", join(workDir, filename), "-C", workDir],
+ // Relative to the work folder: Git's GNU tar, which a bash step on Windows runs, reads
+ // `D:\...` as a remote host.
+ ["tar", "-xzf", filename, "-C", "."],
workDir,
);
const pkgDir = join(workDir, "package");
diff --git a/desktop/scripts/release-cli-bundle.test.ts b/desktop/scripts/release-cli-bundle.test.ts
new file mode 100644
index 0000000000..4a4d332fab
--- /dev/null
+++ b/desktop/scripts/release-cli-bundle.test.ts
@@ -0,0 +1,243 @@
+/**
+ * Release builds carry the Intelligence CLI.
+ *
+ * The standalone app sets up Intelligence only through the CLI it bundles; a build without it
+ * cannot get past Account. The signed builds are the ones people install, and the Mac one is what
+ * the in-place updater puts on every Mac, so both signing workflows are held to bundling it here,
+ * and the scripts that sign and check the Mac bundle are run on a stand-in.
+ */
+import { afterEach, expect, test } from "bun:test";
+import {
+ copyFileSync,
+ mkdirSync,
+ mkdtempSync,
+ readFileSync,
+ rmSync,
+ writeFileSync,
+} from "node:fs";
+import { tmpdir } from "node:os";
+import { join, resolve } from "node:path";
+import { CLI_OVERLAY, planSignedBuild, type Runner } from "./signed-build";
+
+const repository = resolve(import.meta.dir, "..", "..");
+const scripts = import.meta.dir;
+const directories: string[] = [];
+
+afterEach(() => {
+ for (const directory of directories.splice(0)) {
+ rmSync(directory, { recursive: true, force: true });
+ }
+});
+
+function workflow(name: string): string {
+ return readFileSync(join(repository, ".github", "workflows", name), "utf8");
+}
+
+/** The text of the step called `name`, up to the next step. */
+function step(text: string, name: string): string {
+ const start = text.indexOf(`- name: ${name}\n`);
+ expect(start, `no step "${name}"`).toBeGreaterThan(-1);
+ const rest = text.slice(start + 1);
+ const next = rest.search(/\n {6}- (name|uses):/);
+ return next === -1 ? rest : rest.slice(0, next);
+}
+
+test("the bundle overlay puts the CLI in the app's resources", () => {
+ const overlay = JSON.parse(
+ readFileSync(
+ join(repository, "desktop/src-tauri/tauri.bundled-cli.conf.json"),
+ "utf8",
+ ),
+ );
+ expect(overlay.bundle.resources).toEqual({ "cli-bundle/": "cli-bundle/" });
+});
+
+test("the signed Mac build goes through signed-build.ts and checks the CLI it carries", () => {
+ const text = workflow("desktop-macos-signing.yml");
+ expect(step(text, "Build, sign and notarize")).toContain(
+ 'bun desktop/scripts/signed-build.ts darwin "$ARCH"',
+ );
+ expect(
+ step(text, "Verify the signature, Gatekeeper and the notarization ticket"),
+ ).toContain('desktop/scripts/verify-cli-bundle.sh "$app" developer-id');
+});
+
+test("the signed Windows build goes through signed-build.ts and checks the installer has the CLI", () => {
+ const text = workflow("desktop-signing.yml");
+ expect(step(text, "Build and sign")).toContain("signed-build.ts win32 x64");
+ const verify = step(
+ text,
+ "Verify the installer carries the Intelligence CLI",
+ );
+ expect(verify).toContain("cli-bundle\\runtime\\node.exe");
+ expect(verify).toContain("cli-bundle\\cli\\index.js");
+});
+
+/** A desktop/ folder signed-build.ts can plan for, with the bundled CLI's overlay. */
+function signedDesktop(): string {
+ const dir = mkdtempSync(join(tmpdir(), "openbot-signed-cli-"));
+ directories.push(dir);
+ mkdirSync(join(dir, "src-tauri"));
+ for (const file of [
+ "src-tauri/tauri.macos-signing.conf.json",
+ "src-tauri/tauri.windows-signing.conf.json",
+ "src-tauri/tauri.bundled-cli.conf.json",
+ ]) {
+ copyFileSync(join(repository, "desktop", file), join(dir, file));
+ }
+ writeFileSync(
+ join(dir, "build-version.json"),
+ JSON.stringify({
+ version: "0.3.0",
+ sourceSha: "a".repeat(40),
+ channel: "release",
+ }),
+ );
+ return dir;
+}
+
+function plannedCommands(
+ platform: "darwin" | "win32",
+ signingIdentity?: string,
+) {
+ const dir = signedDesktop();
+ const calls: string[][] = [];
+ const run: Runner = (cmd) => {
+ calls.push(cmd);
+ return { code: 0, stdout: "", stderr: "" };
+ };
+ const plan = planSignedBuild({
+ desktop: dir,
+ platform,
+ arch: platform === "darwin" ? "arm64" : "x64",
+ overlay:
+ platform === "darwin"
+ ? "src-tauri/tauri.macos-signing.conf.json"
+ : "src-tauri/tauri.windows-signing.conf.json",
+ repository: "CopilotKit/OpenBot",
+ workDir: join(dir, "work"),
+ bun: "bun",
+ run,
+ signingIdentity,
+ });
+ return { plan, calls: calls.map((call) => call.join(" ")) };
+}
+
+test("a signed Mac build bundles the CLI, then signs its binaries before the build pins them", () => {
+ const { plan, calls } = plannedCommands(
+ "darwin",
+ "Developer ID Application: Example (TEAM123456)",
+ );
+ expect(calls).toHaveLength(2);
+ expect(calls[0]).toContain("scripts/cli-bundle.ts darwin arm64");
+ expect(calls[1]).toContain("scripts/sign-cli-bundle.sh");
+ expect(calls[1]).toContain("Developer ID Application: Example (TEAM123456)");
+ expect(calls[1]).toContain("cli-bundle.entitlements.plist");
+ expect(plan.configs).toContain(CLI_OVERLAY);
+ expect(plan.env.OPENBOT_BUNDLED_CLI).toBe("1");
+});
+
+test("a signed Windows build bundles the CLI and signs nothing in it itself", () => {
+ const { plan, calls } = plannedCommands("win32");
+ expect(calls).toEqual([
+ expect.stringContaining("scripts/cli-bundle.ts win32 x64"),
+ ]);
+ expect(plan.configs).toContain(CLI_OVERLAY);
+ expect(plan.env.OPENBOT_BUNDLED_CLI).toBe("1");
+});
+
+/** A stand-in OpenBot.app: a signed main program and, unless `withCli` is false, a CLI bundle. */
+function standInApp(withCli = true): string {
+ const root = mkdtempSync(join(tmpdir(), "openbot-cli-bundle-"));
+ directories.push(root);
+ const app = join(root, "OpenBot.app");
+ const macos = join(app, "Contents", "MacOS");
+ mkdirSync(macos, { recursive: true });
+ copyFileSync("/usr/bin/true", join(macos, "openbot-desktop"));
+ if (withCli) {
+ const bundle = join(app, "Contents", "Resources", "cli-bundle");
+ mkdirSync(join(bundle, "runtime"), { recursive: true });
+ mkdirSync(join(bundle, "cli", "node_modules", "addon"), {
+ recursive: true,
+ });
+ copyFileSync("/usr/bin/true", join(bundle, "runtime", "node"));
+ // A native module npm installed, signed by somebody else.
+ copyFileSync(
+ "/usr/bin/true",
+ join(bundle, "cli", "node_modules", "addon", "addon.node"),
+ );
+ writeFileSync(join(bundle, "cli", "index.js"), "console.log('cli');\n");
+ }
+ return app;
+}
+
+function run(command: string[]) {
+ const result = Bun.spawnSync(command, { stdout: "pipe", stderr: "pipe" });
+ return {
+ code: result.exitCode,
+ output: `${result.stdout.toString()}${result.stderr.toString()}`,
+ };
+}
+
+const onMac = process.platform === "darwin";
+
+test.if(onMac)("an app with no CLI fails the check", () => {
+ const app = standInApp(false);
+ const checked = run([join(scripts, "verify-cli-bundle.sh"), app, "adhoc"]);
+ expect(checked.code).not.toBe(0);
+ expect(checked.output).toContain("has no bundled CLI");
+});
+
+test.if(onMac)(
+ "every Mach-O in the bundle is signed hardened, and the runtime without get-task-allow",
+ () => {
+ const app = standInApp();
+ const bundle = join(app, "Contents", "Resources", "cli-bundle");
+ // As Node ships: get-task-allow, which notarization refuses.
+ const debuggable = join(bundle, "debuggable.plist");
+ writeFileSync(
+ debuggable,
+ '\n\ncom.apple.security.get-task-allow\n',
+ );
+ const node = join(bundle, "runtime", "node");
+ expect(
+ run([
+ "codesign",
+ "--force",
+ "--sign",
+ "-",
+ "--options",
+ "runtime",
+ "--entitlements",
+ debuggable,
+ node,
+ ]).code,
+ ).toBe(0);
+ rmSync(debuggable);
+ const before = run([join(scripts, "verify-cli-bundle.sh"), app, "adhoc"]);
+ expect(before.code).not.toBe(0);
+
+ const signed = run([
+ join(scripts, "sign-cli-bundle.sh"),
+ bundle,
+ "-",
+ join(repository, "desktop/src-tauri/cli-bundle.entitlements.plist"),
+ ]);
+ expect(signed.code, signed.output).toBe(0);
+ expect(signed.output).toContain("1 other Mach-O files");
+ const after = run([join(scripts, "verify-cli-bundle.sh"), app, "adhoc"]);
+ expect(after.code, after.output).toBe(0);
+ expect(after.output).toContain("2 Mach-O files");
+ // The runtime keeps what V8 needs under the hardened runtime, and nothing more.
+ const entitlements = run([
+ "codesign",
+ "-d",
+ "--entitlements",
+ "-",
+ "--xml",
+ node,
+ ]);
+ expect(entitlements.output).toContain("com.apple.security.cs.allow-jit");
+ expect(entitlements.output).not.toContain("get-task-allow");
+ },
+);
diff --git a/desktop/scripts/sign-cli-bundle.sh b/desktop/scripts/sign-cli-bundle.sh
new file mode 100755
index 0000000000..5094340e91
--- /dev/null
+++ b/desktop/scripts/sign-cli-bundle.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+# Signs every Mach-O file in the Intelligence CLI bundle a Mac build carries
+# (`tauri.bundled-cli.conf.json`), before `tauri build` pins the runtime's digest (build.rs).
+#
+# Tauri signs the app's own binary and its frameworks, not its resources, and notarization refuses
+# any Mach-O in the app that is not signed with a Developer ID Application certificate, with the
+# hardened runtime and a secure timestamp. The bundle has such files of its own: Node, which ships
+# with `get-task-allow`, and native modules npm installs signed for the Mac App Store. Each is
+# signed again here with this build's identity. Node gets the entitlements V8 needs under the
+# hardened runtime (cli-bundle.entitlements.plist) and nothing else.
+#
+# Usage: sign-cli-bundle.sh
+# An identity of `-` signs ad hoc, with no timestamp, for a local build.
+set -euo pipefail
+
+bundle="${1:?the cli-bundle folder}"
+identity="${2:?the signing identity, or - for ad hoc}"
+entitlements="${3:?the entitlements for the runtime}"
+
+node="$bundle/runtime/node"
+test -f "$node" || { echo "No runtime at $node" >&2; exit 1; }
+timestamp=--timestamp
+if [ "$identity" = "-" ]; then
+ timestamp=--timestamp=none
+fi
+
+others=0
+while IFS= read -r -d '' file; do
+ [ "$file" = "$node" ] && continue
+ case "$(file -b "$file")" in
+ *Mach-O*)
+ codesign --force --sign "$identity" --options runtime "$timestamp" "$file"
+ others=$((others + 1))
+ ;;
+ esac
+done < <(find "$bundle" -type f -print0)
+
+codesign --force --sign "$identity" --options runtime "$timestamp" \
+ --entitlements "$entitlements" "$node"
+codesign --verify --strict "$node"
+echo "Signed the runtime and $others other Mach-O files in $bundle."
diff --git a/desktop/scripts/signed-build.ts b/desktop/scripts/signed-build.ts
index 098476b542..77148cda0b 100644
--- a/desktop/scripts/signed-build.ts
+++ b/desktop/scripts/signed-build.ts
@@ -104,6 +104,8 @@ export function planSignedBuild(options: {
workDir: string;
bun: string;
run: Runner;
+ /** The Developer ID a Mac build signs with. The bundled CLI's binaries are signed with it. */
+ signingIdentity?: string;
}): Plan {
const { desktop, platform, arch, overlay, repository, workDir, run } =
options;
@@ -188,6 +190,22 @@ export function planSignedBuild(options: {
[options.bun, join(desktop, "scripts", "cli-bundle.ts"), platform, arch],
desktop,
);
+ // Notarization refuses any Mach-O in the app that is not signed with a Developer ID, hardened
+ // and timestamped, and Tauri signs none of its resources: Node ships with get-task-allow, and
+ // npm installs native modules signed for the Mac App Store. Signed here, before the build pins
+ // the runtime's digest, since signing rewrites the file.
+ if (platform === "darwin" && options.signingIdentity) {
+ runChecked(
+ run,
+ [
+ join(desktop, "scripts", "sign-cli-bundle.sh"),
+ join(desktop, "src-tauri", "cli-bundle"),
+ options.signingIdentity,
+ join(desktop, "src-tauri", "cli-bundle.entitlements.plist"),
+ ],
+ desktop,
+ );
+ }
plan.configs.push(CLI_OVERLAY);
plan.env.OPENBOT_BUNDLED_CLI = "1";
}
@@ -252,6 +270,8 @@ function main(argv: string[]) {
workDir: join(process.env.RUNNER_TEMP ?? tmpdir(), "signed-build"),
bun,
run: realRun,
+ signingIdentity:
+ platform === "darwin" ? (process.env.APPLE_SIGNING_IDENTITY ?? "") : "",
});
console.log(
plan.pinned
diff --git a/desktop/scripts/verify-cli-bundle.sh b/desktop/scripts/verify-cli-bundle.sh
new file mode 100755
index 0000000000..426be07637
--- /dev/null
+++ b/desktop/scripts/verify-cli-bundle.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+# Checks that a built OpenBot.app carries the Intelligence CLI, and that every Mach-O file in it is
+# signed the way notarization requires: with a Developer ID Application certificate of the app's own
+# team, the hardened runtime, a secure timestamp and no `get-task-allow`. See sign-cli-bundle.sh.
+#
+# Usage: verify-cli-bundle.sh developer-id|adhoc
+# `adhoc` checks a local build, which has no timestamp and no team to compare.
+set -euo pipefail
+
+app="${1:?the .app}"
+mode="${2:?developer-id or adhoc}"
+bundle="$app/Contents/Resources/cli-bundle"
+team="$(codesign -dv --verbose=4 "$app" 2>&1 | sed -n 's/^TeamIdentifier=//p')" || team=""
+if [ "$mode" = developer-id ] && { [ -z "$team" ] || [ "$team" = "not set" ]; }; then
+ echo "::error::$app has no team to compare the CLI's signatures with." >&2
+ exit 1
+fi
+
+for required in runtime/node cli/index.js; do
+ if [ ! -f "$bundle/$required" ]; then
+ echo "::error::$app has no bundled CLI: $required is missing." >&2
+ exit 1
+ fi
+done
+
+checked=0
+while IFS= read -r -d '' file; do
+ case "$(file -b "$file")" in
+ *Mach-O*) ;;
+ *) continue ;;
+ esac
+ name="${file#"$bundle"/}"
+ codesign --verify --strict "$file"
+ details="$(codesign -dv --verbose=4 "$file" 2>&1)"
+ if ! grep -q 'flags=.*runtime' <<<"$details"; then
+ echo "::error::$name does not have the hardened runtime." >&2
+ exit 1
+ fi
+ if [ "$mode" = developer-id ]; then
+ grep -q '^Authority=Developer ID Application: ' <<<"$details" &&
+ grep -qx "TeamIdentifier=$team" <<<"$details" || {
+ echo "::error::$name is not signed with the app's own Developer ID ($team)." >&2
+ exit 1
+ }
+ grep -q '^Timestamp=' <<<"$details" || {
+ echo "::error::$name has no secure timestamp." >&2
+ exit 1
+ }
+ fi
+ if codesign -d --entitlements - --xml "$file" 2>/dev/null | grep -q 'get-task-allow'; then
+ echo "::error::$name requests get-task-allow, which notarization refuses." >&2
+ exit 1
+ fi
+ checked=$((checked + 1))
+done < <(find "$bundle" -type f -print0)
+
+echo "The app carries the CLI; $checked Mach-O files in it are signed for notarization."
diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock
index 3f637e665a..2d9caed03b 100644
--- a/desktop/src-tauri/Cargo.lock
+++ b/desktop/src-tauri/Cargo.lock
@@ -349,6 +349,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+[[package]]
+name = "byteorder-lite"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
+
[[package]]
name = "bytes"
version = "1.12.1"
@@ -1800,6 +1806,19 @@ dependencies = [
"icu_properties",
]
+[[package]]
+name = "image"
+version = "0.25.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104"
+dependencies = [
+ "bytemuck",
+ "byteorder-lite",
+ "moxcms",
+ "num-traits",
+ "png 0.18.1",
+]
+
[[package]]
name = "indexmap"
version = "1.9.3"
@@ -2222,6 +2241,16 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "moxcms"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b"
+dependencies = [
+ "num-traits",
+ "pxfm",
+]
+
[[package]]
name = "muda"
version = "0.20.0"
@@ -2573,6 +2602,7 @@ dependencies = [
"base64 0.22.1",
"flate2",
"libc",
+ "objc2",
"portable-pty",
"rand 0.9.5",
"reqwest 0.12.28",
@@ -2941,6 +2971,12 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "pxfm"
+version = "0.1.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea"
+
[[package]]
name = "quick-xml"
version = "0.41.0"
@@ -4100,6 +4136,7 @@ dependencies = [
"gtk",
"heck 0.5.0",
"http",
+ "image",
"jni 0.21.1",
"libc",
"log",
diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml
index 55bddc3709..4bb31e316b 100644
--- a/desktop/src-tauri/Cargo.toml
+++ b/desktop/src-tauri/Cargo.toml
@@ -15,6 +15,8 @@ path = "src/main.rs"
[build-dependencies]
tauri-build = { version = "2", features = [] }
+# Pins a bundled Intelligence CLI to the bytes the app was built with. See build.rs.
+sha2 = "0.10"
# Reads the pinned deployment manifest an internal or candidate build carries. See `build.rs`.
serde_json = "1"
@@ -23,7 +25,7 @@ default = []
shell-updater = []
[dependencies]
-tauri = { version = "2", features = ["tray-icon"] }
+tauri = { version = "2", features = ["tray-icon", "image-png"] }
tauri-plugin-shell = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
@@ -51,5 +53,15 @@ tauri-plugin-process = "2"
[target.'cfg(unix)'.dependencies]
libc = "0.2"
+# The macOS quit OpenBot did not start (Dock, AppleScript, log out) routed through its own Quit.
+# The version Tauri already uses. See `macos_quit` in main.rs.
+[target.'cfg(target_os = "macos")'.dependencies]
+objc2 = "0.6"
+
[dev-dependencies]
tauri = { version = "2", features = ["test"] }
+
+# Every local evaluation CLI call checks the pinned runtime and script against their digests,
+# about 150 MB. Unoptimized, that hash alone took 4.9 s per call in a debug build; optimized, 0.3 s.
+[profile.dev.package.sha2]
+opt-level = 3
diff --git a/desktop/src-tauri/build.rs b/desktop/src-tauri/build.rs
index 2309f4c3fc..5ba585acda 100644
--- a/desktop/src-tauri/build.rs
+++ b/desktop/src-tauri/build.rs
@@ -30,8 +30,119 @@ fn main() {
);
println!("cargo:rerun-if-env-changed=RUSTC");
println!("cargo:rerun-if-env-changed=PATH");
+ build_identity();
+ bundled_cli();
pin_deployment();
- tauri_build::build()
+ // The one way the OpenBot app's own page reaches the shell: an inline plugin whose commands get
+ // permissions of their own, granted at runtime to the exact owned app origin. App commands stay
+ // out of a remote page's reach.
+ tauri_build::try_build(
+ tauri_build::Attributes::new()
+ .plugin(
+ "openbot-intelligence",
+ tauri_build::InlinedPlugin::new().commands(&["watch", "open"]),
+ )
+ // Settings → This computer: the Status window's facts and actions, from the app.
+ .plugin(
+ "openbot-desktop",
+ tauri_build::InlinedPlugin::new().commands(&[
+ "appearance",
+ "status",
+ "restart",
+ "stop",
+ "intelligence",
+ ]),
+ ),
+ )
+ .expect("the Tauri build failed")
+}
+
+/**
+What "About OpenBot" says about this build: the commit, whether the tree had uncommitted changes,
+the branch, and when it was built.
+
+Several worktrees build this app on one machine, and the window looks the same from all of them,
+so which one is running is otherwise a guess. Rerun on every source change, or the time and the
+dirty mark would be those of whenever this script last happened to run.
+*/
+fn build_identity() {
+ let git = |args: &[&str]| {
+ std::process::Command::new("git")
+ .args(args)
+ .output()
+ .ok()
+ .filter(|output| output.status.success())
+ .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
+ };
+ let commit = git(&["rev-parse", "--short", "HEAD"])
+ .filter(|commit| !commit.is_empty())
+ .unwrap_or_else(|| "unknown".into());
+ let dirty = git(&["status", "--porcelain", "--untracked-files=no"])
+ .is_some_and(|changes| !changes.is_empty());
+ let branch = git(&["branch", "--show-current"]).unwrap_or_default();
+ let built = std::time::SystemTime::now()
+ .duration_since(std::time::UNIX_EPOCH)
+ .map(|since| since.as_secs())
+ .unwrap_or_default();
+ println!(
+ "cargo:rustc-env=OPENBOT_BUILD_COMMIT={commit}{}",
+ if dirty { "-dirty" } else { "" }
+ );
+ println!("cargo:rustc-env=OPENBOT_BUILD_BRANCH={branch}");
+ println!("cargo:rustc-env=OPENBOT_BUILD_TIME={built}");
+ // A commit moves the branch's ref; staging changes the index. Both are under the git dir, which
+ // for a worktree is not `.git` in the checkout.
+ for path in ["HEAD", "index"] {
+ if let Some(path) = git(&["rev-parse", "--git-path", path]) {
+ println!("cargo:rerun-if-changed={path}");
+ }
+ }
+ if let Some(reference) = git(&["symbolic-ref", "-q", "HEAD"]) {
+ if let Some(path) = git(&["rev-parse", "--git-path", &reference]) {
+ println!("cargo:rerun-if-changed={path}");
+ }
+ }
+ println!("cargo:rerun-if-changed=src");
+ println!("cargo:rerun-if-changed=../src");
+}
+
+/**
+The Intelligence CLI a build carries inside the app, pinned to the bytes it was built with.
+
+Only with `OPENBOT_BUNDLED_CLI=1`, from `cli-bundle/` beside this file: `runtime/node` and
+`cli/index.js` (and the CLI's `node_modules`), which `tauri.bundled-cli.conf.json` copies into the
+app's resources. Their digests are compiled in, so the app runs exactly these files and nothing put
+there afterwards. Every other build has no bundled CLI. See `local_eval::bundled_cli`.
+*/
+fn bundled_cli() {
+ println!("cargo:rerun-if-env-changed=OPENBOT_BUNDLED_CLI");
+ if std::env::var("OPENBOT_BUNDLED_CLI").as_deref() != Ok("1") {
+ return;
+ }
+ let root = std::path::Path::new("cli-bundle");
+ // The target's, not `cfg!(windows)`: a build script is compiled for the machine building, so
+ // a Windows app built on a Mac would otherwise pin a `node` that is not there.
+ let windows = std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("windows");
+ let node = format!("node{}", if windows { ".exe" } else { "" });
+ for (variable, path) in [
+ (
+ "OPENBOT_BUNDLED_CLI_PROGRAM_SHA256",
+ root.join("runtime").join(node),
+ ),
+ (
+ "OPENBOT_BUNDLED_CLI_ENTRY_SHA256",
+ root.join("cli").join("index.js"),
+ ),
+ ] {
+ use sha2::Digest;
+ let mut file = std::fs::File::open(&path).unwrap_or_else(|error| {
+ panic!("OPENBOT_BUNDLED_CLI=1 needs {}: {error}", path.display())
+ });
+ let mut hasher = sha2::Sha256::new();
+ std::io::copy(&mut file, &mut hasher).expect("the bundled CLI could not be read");
+ println!("cargo:rustc-env={variable}={:x}", hasher.finalize());
+ println!("cargo:rerun-if-changed={}", path.display());
+ }
}
/// Compile in the deployment named by `OPENBOT_PINNED_DEPLOYMENT`, when there is one.
diff --git a/desktop/src-tauri/capabilities/default.json b/desktop/src-tauri/capabilities/default.json
index 0eb9a813af..1676420311 100644
--- a/desktop/src-tauri/capabilities/default.json
+++ b/desktop/src-tauri/capabilities/default.json
@@ -2,7 +2,7 @@
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "What the setup window is allowed to do. Commands this app defines are always callable; everything under core: is not, and has to be granted here.",
- "windows": ["main"],
+ "windows": ["main", "status"],
"permissions": [
"core:event:default",
{
diff --git a/desktop/src-tauri/cli-bundle.entitlements.plist b/desktop/src-tauri/cli-bundle.entitlements.plist
new file mode 100644
index 0000000000..a3375d70f8
--- /dev/null
+++ b/desktop/src-tauri/cli-bundle.entitlements.plist
@@ -0,0 +1,14 @@
+
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+
+ com.apple.security.cs.disable-library-validation
+
+
+
diff --git a/desktop/src-tauri/gen/schemas/acl-manifests.json b/desktop/src-tauri/gen/schemas/acl-manifests.json
index 3b8d8859b4..20e8eab6df 100644
--- a/desktop/src-tauri/gen/schemas/acl-manifests.json
+++ b/desktop/src-tauri/gen/schemas/acl-manifests.json
@@ -1 +1 @@
-{"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener","allow-supports-multiple-windows"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-exit":{"identifier":"allow-exit","description":"Enables the exit command without any pre-configured scope.","commands":{"allow":["exit"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-supports-multiple-windows":{"identifier":"allow-supports-multiple-windows","description":"Enables the supports_multiple_windows command without any pre-configured scope.","commands":{"allow":["supports_multiple_windows"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-exit":{"identifier":"deny-exit","description":"Denies the exit command without any pre-configured scope.","commands":{"allow":[],"deny":["exit"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-supports-multiple-windows":{"identifier":"deny-supports-multiple-windows","description":"Denies the supports_multiple_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["supports_multiple_windows"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-icon-with-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-icon-with-as-template":{"identifier":"allow-set-icon-with-as-template","description":"Enables the set_icon_with_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_with_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-icon-with-as-template":{"identifier":"deny-set-icon-with-as-template","description":"Denies the set_icon_with_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_with_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-activity-name","allow-scene-identifier","allow-internal-toggle-maximize"]},"permissions":{"allow-activity-name":{"identifier":"allow-activity-name","description":"Enables the activity_name command without any pre-configured scope.","commands":{"allow":["activity_name"],"deny":[]}},"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-scene-identifier":{"identifier":"allow-scene-identifier","description":"Enables the scene_identifier command without any pre-configured scope.","commands":{"allow":["scene_identifier"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-fullscreen-on-monitor":{"identifier":"allow-set-fullscreen-on-monitor","description":"Enables the set_fullscreen_on_monitor command without any pre-configured scope.","commands":{"allow":["set_fullscreen_on_monitor"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-activity-name":{"identifier":"deny-activity-name","description":"Denies the activity_name command without any pre-configured scope.","commands":{"allow":[],"deny":["activity_name"]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-scene-identifier":{"identifier":"deny-scene-identifier","description":"Denies the scene_identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["scene_identifier"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-fullscreen-on-monitor":{"identifier":"deny-set-fullscreen-on-monitor","description":"Denies the set_fullscreen_on_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen_on_monitor"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}},"process":{"default_permission":{"identifier":"default","description":"This permission set configures which\nprocess features are by default exposed.\n\n#### Granted Permissions\n\nThis enables to quit via `allow-exit` and restart via `allow-restart`\nthe application.\n","permissions":["allow-exit","allow-restart"]},"permissions":{"allow-exit":{"identifier":"allow-exit","description":"Enables the exit command without any pre-configured scope.","commands":{"allow":["exit"],"deny":[]}},"allow-restart":{"identifier":"allow-restart","description":"Enables the restart command without any pre-configured scope.","commands":{"allow":["restart"],"deny":[]}},"deny-exit":{"identifier":"deny-exit","description":"Denies the exit command without any pre-configured scope.","commands":{"allow":[],"deny":["exit"]}},"deny-restart":{"identifier":"deny-restart","description":"Denies the restart command without any pre-configured scope.","commands":{"allow":[],"deny":["restart"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"updater":{"default_permission":{"identifier":"default","description":"This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n","permissions":["allow-check","allow-download","allow-install","allow-download-and-install"]},"permissions":{"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-download":{"identifier":"allow-download","description":"Enables the download command without any pre-configured scope.","commands":{"allow":["download"],"deny":[]}},"allow-download-and-install":{"identifier":"allow-download-and-install","description":"Enables the download_and_install command without any pre-configured scope.","commands":{"allow":["download_and_install"],"deny":[]}},"allow-install":{"identifier":"allow-install","description":"Enables the install command without any pre-configured scope.","commands":{"allow":["install"],"deny":[]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-download":{"identifier":"deny-download","description":"Denies the download command without any pre-configured scope.","commands":{"allow":[],"deny":["download"]}},"deny-download-and-install":{"identifier":"deny-download-and-install","description":"Denies the download_and_install command without any pre-configured scope.","commands":{"allow":[],"deny":["download_and_install"]}},"deny-install":{"identifier":"deny-install","description":"Denies the install command without any pre-configured scope.","commands":{"allow":[],"deny":["install"]}}},"permission_sets":{},"global_scope_schema":null}}
\ No newline at end of file
+{"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener","allow-supports-multiple-windows"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-exit":{"identifier":"allow-exit","description":"Enables the exit command without any pre-configured scope.","commands":{"allow":["exit"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-supports-multiple-windows":{"identifier":"allow-supports-multiple-windows","description":"Enables the supports_multiple_windows command without any pre-configured scope.","commands":{"allow":["supports_multiple_windows"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-exit":{"identifier":"deny-exit","description":"Denies the exit command without any pre-configured scope.","commands":{"allow":[],"deny":["exit"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-supports-multiple-windows":{"identifier":"deny-supports-multiple-windows","description":"Denies the supports_multiple_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["supports_multiple_windows"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-icon-with-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-icon-with-as-template":{"identifier":"allow-set-icon-with-as-template","description":"Enables the set_icon_with_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_with_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-icon-with-as-template":{"identifier":"deny-set-icon-with-as-template","description":"Denies the set_icon_with_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_with_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-activity-name","allow-scene-identifier","allow-internal-toggle-maximize"]},"permissions":{"allow-activity-name":{"identifier":"allow-activity-name","description":"Enables the activity_name command without any pre-configured scope.","commands":{"allow":["activity_name"],"deny":[]}},"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-scene-identifier":{"identifier":"allow-scene-identifier","description":"Enables the scene_identifier command without any pre-configured scope.","commands":{"allow":["scene_identifier"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-fullscreen-on-monitor":{"identifier":"allow-set-fullscreen-on-monitor","description":"Enables the set_fullscreen_on_monitor command without any pre-configured scope.","commands":{"allow":["set_fullscreen_on_monitor"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-activity-name":{"identifier":"deny-activity-name","description":"Denies the activity_name command without any pre-configured scope.","commands":{"allow":[],"deny":["activity_name"]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-scene-identifier":{"identifier":"deny-scene-identifier","description":"Denies the scene_identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["scene_identifier"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-fullscreen-on-monitor":{"identifier":"deny-set-fullscreen-on-monitor","description":"Denies the set_fullscreen_on_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen_on_monitor"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null},"openbot-desktop":{"default_permission":null,"permissions":{"allow-appearance":{"identifier":"allow-appearance","description":"Enables the appearance command without any pre-configured scope.","commands":{"allow":["appearance"],"deny":[]}},"allow-intelligence":{"identifier":"allow-intelligence","description":"Enables the intelligence command without any pre-configured scope.","commands":{"allow":["intelligence"],"deny":[]}},"allow-restart":{"identifier":"allow-restart","description":"Enables the restart command without any pre-configured scope.","commands":{"allow":["restart"],"deny":[]}},"allow-status":{"identifier":"allow-status","description":"Enables the status command without any pre-configured scope.","commands":{"allow":["status"],"deny":[]}},"allow-stop":{"identifier":"allow-stop","description":"Enables the stop command without any pre-configured scope.","commands":{"allow":["stop"],"deny":[]}},"deny-appearance":{"identifier":"deny-appearance","description":"Denies the appearance command without any pre-configured scope.","commands":{"allow":[],"deny":["appearance"]}},"deny-intelligence":{"identifier":"deny-intelligence","description":"Denies the intelligence command without any pre-configured scope.","commands":{"allow":[],"deny":["intelligence"]}},"deny-restart":{"identifier":"deny-restart","description":"Denies the restart command without any pre-configured scope.","commands":{"allow":[],"deny":["restart"]}},"deny-status":{"identifier":"deny-status","description":"Denies the status command without any pre-configured scope.","commands":{"allow":[],"deny":["status"]}},"deny-stop":{"identifier":"deny-stop","description":"Denies the stop command without any pre-configured scope.","commands":{"allow":[],"deny":["stop"]}}},"permission_sets":{},"global_scope_schema":null},"openbot-intelligence":{"default_permission":null,"permissions":{"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-watch":{"identifier":"allow-watch","description":"Enables the watch command without any pre-configured scope.","commands":{"allow":["watch"],"deny":[]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-watch":{"identifier":"deny-watch","description":"Denies the watch command without any pre-configured scope.","commands":{"allow":[],"deny":["watch"]}}},"permission_sets":{},"global_scope_schema":null},"opener":{"default_permission":{"identifier":"default","description":"This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer","permissions":["allow-open-url","allow-reveal-item-in-dir","allow-default-urls"]},"permissions":{"allow-default-urls":{"identifier":"allow-default-urls","description":"This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.","commands":{"allow":[],"deny":[]},"scope":{"allow":[{"url":"mailto:*"},{"url":"tel:*"},{"url":"http://*"},{"url":"https://*"}]}},"allow-open-path":{"identifier":"allow-open-path","description":"Enables the open_path command without any pre-configured scope.","commands":{"allow":["open_path"],"deny":[]}},"allow-open-url":{"identifier":"allow-open-url","description":"Enables the open_url command without any pre-configured scope.","commands":{"allow":["open_url"],"deny":[]}},"allow-reveal-item-in-dir":{"identifier":"allow-reveal-item-in-dir","description":"Enables the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":["reveal_item_in_dir"],"deny":[]}},"deny-open-path":{"identifier":"deny-open-path","description":"Denies the open_path command without any pre-configured scope.","commands":{"allow":[],"deny":["open_path"]}},"deny-open-url":{"identifier":"deny-open-url","description":"Denies the open_url command without any pre-configured scope.","commands":{"allow":[],"deny":["open_url"]}},"deny-reveal-item-in-dir":{"identifier":"deny-reveal-item-in-dir","description":"Denies the reveal_item_in_dir command without any pre-configured scope.","commands":{"allow":[],"deny":["reveal_item_in_dir"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this url with, for example: firefox."},"url":{"description":"A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"","type":"string"}},"required":["url"],"type":"object"},{"properties":{"app":{"allOf":[{"$ref":"#/definitions/Application"}],"description":"An application to open this path with, for example: xdg-open."},"path":{"description":"A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"}},"required":["path"],"type":"object"}],"definitions":{"Application":{"anyOf":[{"description":"Open in default application.","type":"null"},{"description":"If true, allow open with any application.","type":"boolean"},{"description":"Allow specific application to open with.","type":"string"}],"description":"Opener scope application."}},"description":"Opener scope entry.","title":"OpenerScopeEntry"}},"process":{"default_permission":{"identifier":"default","description":"This permission set configures which\nprocess features are by default exposed.\n\n#### Granted Permissions\n\nThis enables to quit via `allow-exit` and restart via `allow-restart`\nthe application.\n","permissions":["allow-exit","allow-restart"]},"permissions":{"allow-exit":{"identifier":"allow-exit","description":"Enables the exit command without any pre-configured scope.","commands":{"allow":["exit"],"deny":[]}},"allow-restart":{"identifier":"allow-restart","description":"Enables the restart command without any pre-configured scope.","commands":{"allow":["restart"],"deny":[]}},"deny-exit":{"identifier":"deny-exit","description":"Denies the exit command without any pre-configured scope.","commands":{"allow":[],"deny":["exit"]}},"deny-restart":{"identifier":"deny-restart","description":"Denies the restart command without any pre-configured scope.","commands":{"allow":[],"deny":["restart"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}},"updater":{"default_permission":{"identifier":"default","description":"This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n","permissions":["allow-check","allow-download","allow-install","allow-download-and-install"]},"permissions":{"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-download":{"identifier":"allow-download","description":"Enables the download command without any pre-configured scope.","commands":{"allow":["download"],"deny":[]}},"allow-download-and-install":{"identifier":"allow-download-and-install","description":"Enables the download_and_install command without any pre-configured scope.","commands":{"allow":["download_and_install"],"deny":[]}},"allow-install":{"identifier":"allow-install","description":"Enables the install command without any pre-configured scope.","commands":{"allow":["install"],"deny":[]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-download":{"identifier":"deny-download","description":"Denies the download command without any pre-configured scope.","commands":{"allow":[],"deny":["download"]}},"deny-download-and-install":{"identifier":"deny-download-and-install","description":"Denies the download_and_install command without any pre-configured scope.","commands":{"allow":[],"deny":["download_and_install"]}},"deny-install":{"identifier":"deny-install","description":"Denies the install command without any pre-configured scope.","commands":{"allow":[],"deny":["install"]}}},"permission_sets":{},"global_scope_schema":null}}
\ No newline at end of file
diff --git a/desktop/src-tauri/gen/schemas/capabilities.json b/desktop/src-tauri/gen/schemas/capabilities.json
index d8349ab8cf..e52c7576ca 100644
--- a/desktop/src-tauri/gen/schemas/capabilities.json
+++ b/desktop/src-tauri/gen/schemas/capabilities.json
@@ -1 +1 @@
-{"default":{"identifier":"default","description":"What the setup window is allowed to do. Commands this app defines are always callable; everything under core: is not, and has to be granted here.","local":true,"windows":["main"],"permissions":["core:event:default",{"identifier":"opener:allow-open-url","allow":[{"url":"https://*"},{"url":"http://*"}]},"updater:default","process:allow-restart"]}}
\ No newline at end of file
+{"default":{"identifier":"default","description":"What the setup window is allowed to do. Commands this app defines are always callable; everything under core: is not, and has to be granted here.","local":true,"windows":["main","status"],"permissions":["core:event:default",{"identifier":"opener:allow-open-url","allow":[{"url":"https://*"},{"url":"http://*"}]},"updater:default","process:allow-restart"]}}
\ No newline at end of file
diff --git a/desktop/src-tauri/gen/schemas/desktop-schema.json b/desktop/src-tauri/gen/schemas/desktop-schema.json
index 60fc9642ab..6253b00d77 100644
--- a/desktop/src-tauri/gen/schemas/desktop-schema.json
+++ b/desktop/src-tauri/gen/schemas/desktop-schema.json
@@ -2660,6 +2660,90 @@
"const": "dialog:deny-save",
"markdownDescription": "Denies the save command without any pre-configured scope."
},
+ {
+ "description": "Enables the appearance command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-appearance",
+ "markdownDescription": "Enables the appearance command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the intelligence command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-intelligence",
+ "markdownDescription": "Enables the intelligence command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the restart command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-restart",
+ "markdownDescription": "Enables the restart command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the status command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-status",
+ "markdownDescription": "Enables the status command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the stop command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-stop",
+ "markdownDescription": "Enables the stop command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the appearance command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-appearance",
+ "markdownDescription": "Denies the appearance command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the intelligence command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-intelligence",
+ "markdownDescription": "Denies the intelligence command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the restart command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-restart",
+ "markdownDescription": "Denies the restart command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the status command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-status",
+ "markdownDescription": "Denies the status command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the stop command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-stop",
+ "markdownDescription": "Denies the stop command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the open command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:allow-open",
+ "markdownDescription": "Enables the open command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the watch command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:allow-watch",
+ "markdownDescription": "Enables the watch command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the open command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:deny-open",
+ "markdownDescription": "Denies the open command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the watch command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:deny-watch",
+ "markdownDescription": "Denies the watch command without any pre-configured scope."
+ },
{
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer\n#### This default permission set includes:\n\n- `allow-open-url`\n- `allow-reveal-item-in-dir`\n- `allow-default-urls`",
"type": "string",
diff --git a/desktop/src-tauri/gen/schemas/macOS-schema.json b/desktop/src-tauri/gen/schemas/macOS-schema.json
index 60fc9642ab..6253b00d77 100644
--- a/desktop/src-tauri/gen/schemas/macOS-schema.json
+++ b/desktop/src-tauri/gen/schemas/macOS-schema.json
@@ -2660,6 +2660,90 @@
"const": "dialog:deny-save",
"markdownDescription": "Denies the save command without any pre-configured scope."
},
+ {
+ "description": "Enables the appearance command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-appearance",
+ "markdownDescription": "Enables the appearance command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the intelligence command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-intelligence",
+ "markdownDescription": "Enables the intelligence command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the restart command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-restart",
+ "markdownDescription": "Enables the restart command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the status command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-status",
+ "markdownDescription": "Enables the status command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the stop command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:allow-stop",
+ "markdownDescription": "Enables the stop command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the appearance command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-appearance",
+ "markdownDescription": "Denies the appearance command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the intelligence command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-intelligence",
+ "markdownDescription": "Denies the intelligence command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the restart command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-restart",
+ "markdownDescription": "Denies the restart command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the status command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-status",
+ "markdownDescription": "Denies the status command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the stop command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-desktop:deny-stop",
+ "markdownDescription": "Denies the stop command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the open command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:allow-open",
+ "markdownDescription": "Enables the open command without any pre-configured scope."
+ },
+ {
+ "description": "Enables the watch command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:allow-watch",
+ "markdownDescription": "Enables the watch command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the open command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:deny-open",
+ "markdownDescription": "Denies the open command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the watch command without any pre-configured scope.",
+ "type": "string",
+ "const": "openbot-intelligence:deny-watch",
+ "markdownDescription": "Denies the watch command without any pre-configured scope."
+ },
{
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer\n#### This default permission set includes:\n\n- `allow-open-url`\n- `allow-reveal-item-in-dir`\n- `allow-default-urls`",
"type": "string",
diff --git a/desktop/src-tauri/icons/menu/about-dark.png b/desktop/src-tauri/icons/menu/about-dark.png
new file mode 100644
index 0000000000..1d62ae7bef
Binary files /dev/null and b/desktop/src-tauri/icons/menu/about-dark.png differ
diff --git a/desktop/src-tauri/icons/menu/about-light.png b/desktop/src-tauri/icons/menu/about-light.png
new file mode 100644
index 0000000000..491e47adcd
Binary files /dev/null and b/desktop/src-tauri/icons/menu/about-light.png differ
diff --git a/desktop/src-tauri/icons/menu/dashboard-dark.png b/desktop/src-tauri/icons/menu/dashboard-dark.png
new file mode 100644
index 0000000000..1d27fa10be
Binary files /dev/null and b/desktop/src-tauri/icons/menu/dashboard-dark.png differ
diff --git a/desktop/src-tauri/icons/menu/dashboard-light.png b/desktop/src-tauri/icons/menu/dashboard-light.png
new file mode 100644
index 0000000000..fb9a335929
Binary files /dev/null and b/desktop/src-tauri/icons/menu/dashboard-light.png differ
diff --git a/desktop/src-tauri/icons/menu/draw.py b/desktop/src-tauri/icons/menu/draw.py
new file mode 100644
index 0000000000..4cd5a41e08
--- /dev/null
+++ b/desktop/src-tauri/icons/menu/draw.py
@@ -0,0 +1,122 @@
+"""Draws the menu bar menu's icons: thin, geometric, one stroke weight, in the CopilotKit style.
+
+macOS does not treat these as template images, so each is drawn twice, in the light menu's ink and
+the dark menu's, and the app picks by the system appearance. 36px squares: muda shows menu icons
+18pt high, and these are for 2x screens.
+
+Run with `python3 draw.py` from this directory; it needs nothing beyond the standard library.
+"""
+
+import math
+import struct
+import zlib
+
+SIZE = 36
+SAMPLES = 4 # per axis, for anti-aliasing
+STROKE = 2.6 # px at 36px, about 1.3pt
+
+
+def seg_dist(px, py, ax, ay, bx, by):
+ dx, dy = bx - ax, by - ay
+ t = max(0.0, min(1.0, ((px - ax) * dx + (py - ay) * dy) / (dx * dx + dy * dy or 1)))
+ return math.hypot(px - (ax + t * dx), py - (ay + t * dy))
+
+
+def arc_dist(px, py, cx, cy, r, start, end):
+ """Distance to an arc from `start` to `end` radians, counterclockwise in screen terms."""
+ angle = math.atan2(py - cy, px - cx) % (2 * math.pi)
+ s, e = start % (2 * math.pi), end % (2 * math.pi)
+ inside = s <= angle <= e if s <= e else angle >= s or angle <= e
+ if inside:
+ return abs(math.hypot(px - cx, py - cy) - r)
+ return min(
+ math.hypot(px - (cx + r * math.cos(a)), py - (cy + r * math.sin(a))) for a in (s, e)
+ )
+
+
+def rounded_rect_dist(px, py, x0, y0, x1, y1, r):
+ cx, cy = min(max(px, x0 + r), x1 - r), min(max(py, y0 + r), y1 - r)
+ return abs(math.hypot(px - cx, py - cy) - r) if (px < x0 + r or px > x1 - r) and (py < y0 + r or py > y1 - r) else min(
+ abs(px - x0) if y0 + r <= py <= y1 - r else 1e9,
+ abs(px - x1) if y0 + r <= py <= y1 - r else 1e9,
+ abs(py - y0) if x0 + r <= px <= x1 - r else 1e9,
+ abs(py - y1) if x0 + r <= px <= x1 - r else 1e9,
+ abs(math.hypot(px - cx, py - cy) - r),
+ )
+
+
+def dot_dist(px, py, cx, cy, r):
+ return max(0.0, math.hypot(px - cx, py - cy) - r) - STROKE / 2
+
+
+# Each icon: a function from a point to its distance from the drawing.
+ICONS = {
+ # A window: rounded frame with a title bar line.
+ "open": lambda x, y: min(
+ rounded_rect_dist(x, y, 6, 8, 30, 28, 3.5),
+ seg_dist(x, y, 6, 13.5, 30, 13.5),
+ ),
+ # A dashboard: three bars of rising height on a baseline.
+ "dashboard": lambda x, y: min(
+ seg_dist(x, y, 9, 28, 9, 20),
+ seg_dist(x, y, 18, 28, 18, 13),
+ seg_dist(x, y, 27, 28, 27, 8),
+ ),
+ # Status: a pulse line.
+ "status": lambda x, y: min(
+ seg_dist(x, y, 5, 19, 12, 19),
+ seg_dist(x, y, 12, 19, 15.5, 10),
+ seg_dist(x, y, 15.5, 10, 20.5, 27),
+ seg_dist(x, y, 20.5, 27, 24, 19),
+ seg_dist(x, y, 24, 19, 31, 19),
+ ),
+ # About: an "i" in a ring.
+ "about": lambda x, y: min(
+ arc_dist(x, y, 18, 18, 12, 0, 2 * math.pi - 1e-6),
+ seg_dist(x, y, 18, 17, 18, 25),
+ dot_dist(x, y, 18, 12.3, 0),
+ ),
+ # Quit: the power symbol, an open ring with a stem.
+ "quit": lambda x, y: min(
+ arc_dist(x, y, 18, 19.5, 10, math.radians(-50), math.radians(230)),
+ seg_dist(x, y, 18, 6.5, 18, 17),
+ ),
+}
+
+
+def render(shape, ink):
+ rows = []
+ for j in range(SIZE):
+ row = bytearray([0]) # filter: none
+ for i in range(SIZE):
+ covered = 0
+ for sj in range(SAMPLES):
+ for si in range(SAMPLES):
+ x = i + (si + 0.5) / SAMPLES
+ y = j + (sj + 0.5) / SAMPLES
+ if shape(x, y) <= STROKE / 2:
+ covered += 1
+ alpha = round(255 * covered / (SAMPLES * SAMPLES))
+ row += bytes((*ink, alpha))
+ rows.append(bytes(row))
+ raw = b"".join(rows)
+
+ def chunk(kind, data):
+ body = kind + data
+ return struct.pack(">I", len(data)) + body + struct.pack(">I", zlib.crc32(body) & 0xFFFFFFFF)
+
+ header = struct.pack(">IIBBBBB", SIZE, SIZE, 8, 6, 0, 0, 0)
+ return (
+ b"\x89PNG\r\n\x1a\n"
+ + chunk(b"IHDR", header)
+ + chunk(b"IDAT", zlib.compress(raw, 9))
+ + chunk(b"IEND", b"")
+ )
+
+
+if __name__ == "__main__":
+ for name, shape in ICONS.items():
+ for theme, ink in (("light", (0x01, 0x05, 0x07)), ("dark", (0xFF, 0xFF, 0xFF))):
+ with open(f"{name}-{theme}.png", "wb") as out:
+ out.write(render(shape, ink))
+ print(f"{name}-{theme}.png")
diff --git a/desktop/src-tauri/icons/menu/open-dark.png b/desktop/src-tauri/icons/menu/open-dark.png
new file mode 100644
index 0000000000..f00561bacf
Binary files /dev/null and b/desktop/src-tauri/icons/menu/open-dark.png differ
diff --git a/desktop/src-tauri/icons/menu/open-light.png b/desktop/src-tauri/icons/menu/open-light.png
new file mode 100644
index 0000000000..b9cd9dbdc8
Binary files /dev/null and b/desktop/src-tauri/icons/menu/open-light.png differ
diff --git a/desktop/src-tauri/icons/menu/quit-dark.png b/desktop/src-tauri/icons/menu/quit-dark.png
new file mode 100644
index 0000000000..4da5148c48
Binary files /dev/null and b/desktop/src-tauri/icons/menu/quit-dark.png differ
diff --git a/desktop/src-tauri/icons/menu/quit-light.png b/desktop/src-tauri/icons/menu/quit-light.png
new file mode 100644
index 0000000000..bf35811600
Binary files /dev/null and b/desktop/src-tauri/icons/menu/quit-light.png differ
diff --git a/desktop/src-tauri/icons/menu/status-dark.png b/desktop/src-tauri/icons/menu/status-dark.png
new file mode 100644
index 0000000000..7cd23fc32b
Binary files /dev/null and b/desktop/src-tauri/icons/menu/status-dark.png differ
diff --git a/desktop/src-tauri/icons/menu/status-light.png b/desktop/src-tauri/icons/menu/status-light.png
new file mode 100644
index 0000000000..c2bd9c2a0b
Binary files /dev/null and b/desktop/src-tauri/icons/menu/status-light.png differ
diff --git a/desktop/src-tauri/src/acquire.rs b/desktop/src-tauri/src/acquire.rs
index 9bcbb94b4c..37c623fc94 100644
--- a/desktop/src-tauri/src/acquire.rs
+++ b/desktop/src-tauri/src/acquire.rs
@@ -9,6 +9,14 @@
//! needs elevation. So the two halves run in different contexts, and the elevated half is the only
//! part that may be handed to a helper. See `windows.rs`. Fetching and installing Podman itself is
//! `install.rs`.
+//!
+//! **The machine is rootful.** Local Intelligence runs a k3d cluster, and the Intelligence CLI
+//! accepts Podman only in rootful mode, because k3d's node needs privileges a rootless engine
+//! cannot grant. A rootful machine is the same VM with three things changed: its default
+//! connection is `-root`, `/var/run/docker.sock` inside it is the rootful socket, and the API
+//! socket it forwards to this computer is the rootful one. OpenBot's own containers are addressed
+//! through `-root` as well (see `connection_for`), so OpenBot and Intelligence share one
+//! engine and the supervisor's mount of `/var/run/docker.sock` is the engine it was started by.
use crate::quiet::said as command_said;
use std::net::Ipv4Addr;
@@ -80,7 +88,135 @@ impl StepOutcome {
pub const MACHINE: &str = "openbot";
const USER_MODE_NETWORKING_FLAG: &str = "--user-mode-networking=true";
+const ROOTFUL_FLAG: &str = "--rootful";
const HOST_GATEWAY_CONFIG: &str = ".config/containers/containers.conf.d/90-openbot-host.conf";
+/// Where a rootful engine reads the same setting. Root's own `~/.config` is not read by rootful
+/// Podman, and the API service a rootful machine runs is the system one, not a user unit.
+const ROOTFUL_HOST_GATEWAY_CONFIG: &str = "/etc/containers/containers.conf.d/90-openbot-host.conf";
+
+/// The connection that reaches a machine's engine in the mode the machine runs in.
+///
+/// `podman machine init` makes two connections for every machine, whatever its mode: ``,
+/// which logs in as the machine's user and reaches the rootless engine, and `-root`, which
+/// reaches the rootful one. The machine's own mode decides only which of the two is the default,
+/// which socket `/var/run/docker.sock` is inside it, and which API it forwards to this computer.
+/// Addressing a rootful machine by its bare name would put OpenBot's containers in the rootless
+/// engine beside a rootful one, with the supervisor mounting a socket it cannot open. The one
+/// exception is an OpenBot that already lives there (see `connection_keeping_openbot`).
+pub fn connection_for(machine: &str, rootful: bool) -> String {
+ if rootful {
+ format!("{machine}-root")
+ } else {
+ machine.to_string()
+ }
+}
+
+/// The connection to address a running machine through: the one for its mode, unless OpenBot's
+/// database is only in the other one's storage.
+///
+/// The two engines in one machine keep separate containers and volumes. Releases up to 0.2.0
+/// reached every machine by its bare name, so an OpenBot that adopted somebody's rootful machine,
+/// or whose own machine was switched to rootful since, has its database in the rootless engine's
+/// storage. Moving it to `-root` would open it on an empty database with the old one
+/// unreachable beside it, so it stays where it is. Only a rootful machine is asked: a rootless one
+/// was always reached by its bare name.
+fn connection_keeping_openbot(
+ machine: &str,
+ rootful: bool,
+ holds_openbot: impl Fn(&str) -> bool,
+) -> String {
+ let own = connection_for(machine, rootful);
+ if rootful && !holds_openbot(&own) && holds_openbot(machine) {
+ return machine.to_string();
+ }
+ own
+}
+
+/// Whether OpenBot's database volume is in the engine behind `connection`.
+///
+/// By Compose's own label for the volume rather than by its full name, which carries the
+/// deployment folder's name. Any project's `postgres-data` counts: a false yes keeps the
+/// connection a release up to 0.2.0 would have used, and a false no is the one that loses data.
+fn holds_openbot(connection: &str) -> bool {
+ podman(&[
+ "--connection",
+ connection,
+ "volume",
+ "ls",
+ "--quiet",
+ "--filter",
+ "label=com.docker.compose.volume=postgres-data",
+ ])
+ .is_ok_and(|listing| !listing.is_empty())
+}
+
+/// The machine a connection belongs to, by the naming `connection_for` describes.
+fn machine_of(connection: &str) -> &str {
+ connection.strip_suffix("-root").unwrap_or(connection)
+}
+
+/// What `podman machine inspect` says about one machine that matters here.
+#[derive(Debug, Default, PartialEq, Eq)]
+pub struct MachineFacts {
+ /// `None` when inspect did not say, which no supported Podman does.
+ pub rootful: Option,
+ /// The engine API this machine forwards to this computer: a Unix socket on macOS, a named pipe
+ /// on Windows, as a `unix://` or `npipe://` address.
+ pub api: Option,
+}
+
+fn machine_facts(listing: &str, machine: &str) -> Result {
+ let machines: Vec = serde_json::from_str(listing)
+ .map_err(|error| format!("could not read podman machine inspect JSON: {error}"))?;
+ let found = machines
+ .iter()
+ .find(|entry| entry.get("Name").and_then(Value::as_str) == Some(machine))
+ .ok_or_else(|| format!("podman machine inspect did not return {machine}"))?;
+ let path = |key: &str| {
+ found
+ .pointer(&format!("/ConnectionInfo/{key}/Path"))
+ .and_then(Value::as_str)
+ .filter(|path| !path.is_empty())
+ };
+ // The pipe first: Windows reports a pipe, and a socket path beside it is not one this
+ // computer can open.
+ let api = path("PodmanPipe")
+ .map(pipe_address)
+ .or_else(|| path("PodmanSocket").map(|socket| format!("unix://{socket}")));
+ Ok(MachineFacts {
+ rootful: found.get("Rootful").and_then(Value::as_bool),
+ api,
+ })
+}
+
+/// `\\.\pipe\podman-openbot` as the `npipe:////./pipe/podman-openbot` that Docker clients, k3d and
+/// the Intelligence CLI read.
+fn pipe_address(pipe: &str) -> String {
+ format!("npipe://{}", pipe.replace('\\', "/"))
+}
+
+/// What the machine behind a Podman connection is, or why that could not be found.
+///
+/// A connection that is not a machine's (a remote host somebody added) answers with an error, and
+/// the caller then leaves the engine to find its own way.
+pub fn machine_behind(connection: &str) -> Result {
+ let machine = machine_of(connection);
+ machine_facts(&podman(&["machine", "inspect", machine])?, machine)
+}
+
+/// The connection for a machine found by name, in the mode it runs in, or where its OpenBot
+/// already is (see `connection_keeping_openbot`).
+///
+/// A machine that cannot be inspected keeps its bare name, which is how it was addressed before
+/// machines were rootful.
+pub fn connection_of_machine(machine: &str) -> String {
+ let rootful = podman(&["machine", "inspect", machine])
+ .and_then(|listing| machine_facts(&listing, machine))
+ .ok()
+ .and_then(|facts| facts.rootful)
+ .unwrap_or(false);
+ connection_keeping_openbot(machine, rootful, holds_openbot)
+}
fn podman(args: &[&str]) -> Result {
podman_with(args, || {
@@ -148,6 +284,18 @@ pub fn machine_exists() -> Result {
/// No `--provider`: `applehv` has been the default on Apple silicon since Podman 6.1, and pinning it
/// asks for what you already get. The libkrun bind-mount trouble that the pin was written for
/// belonged to 5.7, where libkrun was the default.
+///
+/// `--rootful`, for local Intelligence: see the module comment.
+///
+/// AN EXISTING MACHINE IS NEVER SWITCHED TO ROOTFUL, OURS INCLUDED. `podman machine set --rootful`
+/// would do it, on a stopped machine, which is the person's to stop. A rootless machine keeps its
+/// containers and volumes in the rootless engine's storage, and the rootful engine in the same VM
+/// does not see them. Releases up to 0.2.0 created this machine rootless, so "ours" is not
+/// "empty". A rootless machine is left as it is and OpenBot keeps running on it; local
+/// Intelligence then declines to start there with a sentence that names the switch (see
+/// `local_eval::Failure::RootlessPodman`). After the switch OpenBot stays in the rootless storage
+/// its database is in (see `connection_keeping_openbot`), and Intelligence runs on the rootful
+/// engine of the same machine.
pub fn create_machine(cpus: u32, memory_mib: u32, disk_gib: u32) -> StepOutcome {
create_machine_with(cpus, memory_mib, disk_gib, machine_exists, podman)
}
@@ -190,6 +338,7 @@ fn create_machine_args(
memory_mib.to_string(),
"--disk-size".to_string(),
disk_gib.to_string(),
+ ROOTFUL_FLAG.to_string(),
];
if target_is_windows {
args.push(USER_MODE_NETWORKING_FLAG.to_string());
@@ -201,14 +350,19 @@ fn create_machine_args(
struct MachineNetworking {
state: String,
user_mode: bool,
+ /// Decides where the host-gateway setting is written. Absent reads as rootless, which is what
+ /// every machine was before this app created them rootful.
+ rootful: bool,
}
+/// Answers with the machine's networking on Windows, where the gateway is configured after start,
+/// and with nothing elsewhere.
fn prepare_user_mode_networking_before_start(
run: &mut impl FnMut(&[&str]) -> Result,
target_is_windows: bool,
-) -> Result<(), String> {
+) -> Result