MutkaMutka
Modules

Permissions & Capabilities

The complete capability vocabulary and the permission each one requires — the one file that defines everything a module can do.

Every privileged operation a module can perform is a capability, and each capability requires a declared permission. The mapping lives in exactly one file — capabilities.ts. If an operation isn't listed there, no module can perform it. To expose something new, you add it there and nowhere else.

This page is the full reference. The narrative pages (virtual file systems, declarative UI, storage/network/secrets) explain the why behind each group.

The permission enum

ModulePermission is the closed set a module may declare:

PermissionGrants
fs:readRead directory contents and file metadata/bytes
fs:writeCreate, modify, move, or delete files/directories
fs:tempWrite a short-lived file to the OS temp dir (weaker than fs:write)
clipboard:readRead clipboard contents
clipboard:writeWrite to the native clipboard
navigationChange the active directory / drive tabs
viewControl view state: selection, sort, filters, home, settings
dialogShow prompts, confirmations, choosers
network:publicHTTPS to public domains only (no IPs/localhost)
network:localhttp/https to a private IP range or localhost
storageRead/write its own per-module persisted config
secretsRead/write its own credentials in the macOS Keychain
uiRender declarative panels/popups/settings + status-bar items
discoveryContribute a module-discovery source + probe fetched sources
shellReserved — declared but no capability backs it yet

Network is two least-privilege tiers

There is no blanket network permission. network:public enforces HTTPS to public domains (blocking SSRF to cloud metadata and LAN services); network:local allows a self-hosted server or NAS on a private IP / localhost. A module declares whichever it needs (or both). The URL is classified and enforced in Rust — and a module cannot make native fetch/WebSocket calls at all, so host.net is its only egress.

Capability → permission map

Every host.* call below is gated. gateway.ts checks the required permission against the module's manifest before running; if it's missing, the call throws — and for a worker (community) module the capability is physically unreachable, since the worker has no invoke.

Files & clipboard

CapabilityPermissionBacked by
fs.readDir, fs.openItemfs:readFileSystemRegistry (local or provider)
fs.readBytesfs:readRust read_file_base64Uint8Array
fs.cloudStatusfs:readRust cloud_status (cloud-only vs local)
fs.copyFiles / moveFiles / trashItem / deleteItem / renameItem / createFile / createFolderfs:writeFileSystemRegistry (trashItem = recoverable OS Trash; deleteItem = permanent)
board.readFilesclipboard:readRust clipboard_read_files
board.writeFilesclipboard:writeRust clipboard_write_files
CapabilityPermissionBacked by
nav.navigate / goBack / goForward / goUpnavigationAppBridge
tabs.openTab / openTabInBackground / isActivenavigationTabManager
app.refreshfs:readAppBridge
app.activatenavigationModuleRegistry (open pipeline)
selection.setviewSelectionStore
view.setSort / toggleSortviewListingStore
view.toggleHidden / setShowHiddenviewViewStore
home.getfs:readHomeStore (the app home dir)
home.setviewHomeStore (any module may override)
settings.toggleviewSettingsStore (the overlay)

Dialogs & declarative UI

CapabilityPermissionBacked by
dialog.prompt / confirm / choosedialogAppBridge → <Dialog>
ui.render / clear / modaluiUIStore (UINode surfaces + modal)
statusbar.set / removeuiStatusBarStore

Storage, network & secrets

CapabilityPermissionBacked by
config.get / setstoragelocalStorage, namespaced per module
secrets.get / set / deletesecretsRust secret_* → macOS Keychain (per module)
net.request / download / uploadnetwork:public or network:localRust http_* (host-proxied, URL tier-checked)

System

CapabilityPermissionBacked by
sys.homeDirfs:readRust get_home_dir (the OS home dir)
sys.appVersionstorageRust get_app_version (app build version; non-sensitive, so storage not fs:read)
sys.lastDirfs:readlocalStorage (last dir, for launch restore)
sys.writeTempFilefs:tempRust write_temp_file (OS temp dir only)
sys.quickLook / previewUpdatefs:readRust Quick Look panel
sys.appsForFile / openWithfs:readRust Launch Services ("Open With")
sys.startDragfs:readDragService (native OS file drag-out)

fs:temp is weaker than fs:write

fs:temp writes only to the OS temp directory, so it is deliberately weaker than fs:write — e.g. core.drop-import uses it to stage Finder drops before copying them in, and net.download uses it to land a remote file.

Why when is data, not a function

A worker module can't hand a predicate across postMessage, so command and column visibility is described declaratively and evaluated host-side by whenClause.ts. That's why when: { selection: "single" } is an object, not a callback (VS Code uses string when-clauses for the same reason). Multiple keys AND together.

A command's when.selection accepts:

ValueVisible when…
anyalways
nonenothing is selected
someone or more selected
singleexactly one item
multipletwo or more
singleDirexactly one, a directory
singleFileexactly one, a file
filesone+ and all are files
dirsone+ and all are directories

when.clipboard: "hasItems" additionally gates on a non-empty clipboard (for a Paste command).

On this page