Skip to content

On-disk layout

sf-deck stores its own settings and state under ~/.sf-deck/.

~/.sf-deck/
├── settings.toml             chips, theme, per-org safety overrides
├── cache.db                  local read-cache (SQLite)
├── usage.db                  aggregate API-call counters (SQLite)
├── devprojects.db            projects, tags, histories, saved comparisons, ...
├── keybindings.toml          optional user keymap overrides
├── update-state.json         cached stable-release check
├── instances.json            running-instance registry
├── control-<N>.sock          per-instance IPC socket (when --control is on)
├── deploy.log                optional metadata-deploy diagnostics
└── log/                      private session logs, dumps, and optional traces

settings.toml

Plain TOML. Editable, but go through sf-deck commands rather than hand-editing — sf-deck rewrites the file when settings change and may overwrite manual edits.

Sections:

  • [ui] — theme, sidebar defaults, policy-acceptance revision, and other UI preferences
  • [ui.api] — API timeouts (HTTP, CLI, retrieve/deploy, deploy polling, bulk polling)
  • [ui.updates] — automatic stable-release discovery (enabled by default)
  • [org.<username>] — per-org overrides, including safety = "..." and any per-org pinned chips
  • [[chips.records]] / [[chips.objects]] / [[chips.flows]] … — saved chips by domain
  • [[recent]] — visited-row log per org

cache.db

SQLite. Two top-level tables:

  • orgs — one row per known org (alias, username, instance_url, sandbox flag, last_used, …). Populated when the TUI refreshes the org list via sf org list. Same source the CLI's org-resolver reads.
  • kv — per-org key/value JSON blobs. Used to memoize metadata and catalogue data such as describes, sObject lists, FLS grids, flows, and packages. Composite primary key (org_username, key).

Blobs are opaque from outside — keys such as describe_v3:Account and flows_v2 match what the loaders expect. Don't hand-edit.

Record payloads are never written here. Record lists/details, Salesforce RecentlyViewed rows, SOQL/report rows, related-record lookups, and list-view results are process-memory only. Startup clears their reserved cache prefixes to enforce this boundary.

Safe to delete cache.db at any time; sf-deck rebuilds it on next launch.

devprojects.db

SQLite. Holds the modern feature set:

  • dev_projects — your collected working sets
  • dev_project_items — per-project items, keyed by (project_id, org_user, kind, ref)
  • bundles — sfdx project directories linked to dev projects
  • tags + tag_bindings — tags applied to items
  • saved_queries — your SOQL library
  • saved_apex — your apex snippet library
  • soql_history — every SOQL run (both TUI and CLI)
  • apex_history — every anonymous Apex execution
  • saved_comparisons — saved comparison definitions and compressed metadata snapshots

apex_history includes submitted Apex, status and error details, and the full debug-log body when log capture is enabled for that execution.

Schema migrations are applied automatically on Store.Open.

usage.db

SQLite. Holds daily aggregate API-call counts by org alias, command bucket, and success status. It does not store request or response bodies, Salesforce access tokens, SOQL text, or record rows. The file is forced to owner-only (0600) permissions whenever it is opened.

keybindings.toml

Optional. If present, overrides individual key bindings.

Dump the current defaults as a starting template:

sf-deck --dump-keymap > ~/.sf-deck/keybindings.toml

Then edit the TOML; sf-deck loads it on next launch.

The full keymap reference is at Reference → Keymap.

instances.json

The running-instance registry. One entry per live sf-deck process, written on startup and removed (best-effort) on clean shutdown.

{
  "instances": [
    {
      "number": 1,
      "pid": 12345,
      "started_at": "2026-06-27T13:11:55Z",
      "socket": "/Users/you/.sf-deck/control-1.sock",
      "label": "dev"
    }
  ]
}

Read via sf-deck instance list --json — that's what an IPC-driving agent uses to discover sockets.

Stale entries (pid no longer running) are pruned on read.

update-state.json

A non-sensitive cache containing the last GitHub Releases check time and the latest stable release metadata or a failed-attempt flag. Automatic checks reuse successful and failed attempts for 24 hours. It contains no Salesforce data, credentials, machine identifier, or analytics.

Safe to delete at any time. The next enabled automatic check recreates it. Disable automatic checks in Settings → Updates or with SF_DECK_NO_UPDATE_CHECK=1. An explicit sf-deck update check --force bypasses the cache but still never downloads or installs anything.

Logs, dumps, and diagnostic traces

Session logs live under ~/.sf-deck/log/. Failed report or browser-session exports can also preserve a raw Salesforce response under ~/.sf-deck/log/dumps/ so the failure can be inspected. Dumps are private files and are pruned automatically, but may contain Salesforce-derived values from the failed response.

Diagnostic environment variables such as SF_DECK_API_TRACE, SF_DECK_RENDER_TRACE, and SFDECK_DEBUG_DEPLOY create additional private files. They are off by default. API traces redact SOQL text but can contain org aliases, request paths, and errors. Render traces contain layout and timing information rather than rendered screen text. deploy.log can contain metadata names, deployment IDs, response details, and errors.

The diagnostic output boundary removes active Salesforce access tokens and recognised credential formats before writing. This is defence in depth, not a reason to publish diagnostic files: metadata names, aliases, errors, and user-authored values may still be sensitive.

Bundle directories

By default sf-deck writes bundles into ~/sf-deck-bundles/<project>-<unix-ts>/. Each bundle dir is a complete sfdx project — you can cd into it and run the sf CLI directly if you want.

You can override the default by passing --path to bundle create, or by registering an existing directory with bundle link.

What sf-deck doesn't store

  • Salesforce session tokens — those stay in the sf CLI's keychain / ~/.sfdx/. sf-deck reuses the sf session.
  • Org credentials — same.
  • Normal Salesforce record and query-result payloads in its persistent cache. Metadata/schema and catalogue data may be cached, and the histories, comparisons, exports, dumps, and explicitly enabled diagnostics described above are stored separately.

Inspect and erase

sf-deck data inspect
sf-deck data erase --yes

Close all running sf-deck processes before erasing. Add --include-bundles to remove the default ~/sf-deck-bundles/ directory too. Exports and bundles at custom paths remain at those paths.

Deleting ~/.sf-deck/ does not revoke Salesforce CLI authentication. Use sf-deck org logout --org <alias-or-username> --yes to disconnect a local org session.

Versioning the layout

File Schema version
cache.db tracked in a meta table; auto-migrated
devprojects.db same
settings.toml unversioned; sf-deck reads only the keys it knows about
update-state.json unversioned disposable cache

Schema migrations are forward-only. Downgrading the binary may fail to open a newer DB.