The full list. For how sofka compares to k9s, see vs k9s.
-
Terminal title shows
sofka: <context>/<namespace>and follows navigation. The namespace isallwhen all namespaces are selected. Setterminal_title = falseto disable title changes. Sofka clears the title on exit. -
Compact startup - set
compact_mode = trueto start with a one-line header and no footer.Ctrl-Etoggles the layout for the session; reloads and context switches preserve it. -
Optional header - set
hide_header = truein the configuration to hide the header and logo, including the one-line header in compact mode. -
Connect to the current kubeconfig context, including exec credential plugins (GKE, EKS, and friends).
-
Optional v1 client certificates through
--allow-v1-client-cert, disabled by default. See certificate compatibility. -
Teleport local proxy certificates work when the server certificate exactly matches a configured CA. Hostname, date, usage, and TLS signature checks remain enabled. See proxy certificates.
-
API discovery of every resource type on the cluster, with k9s-style short aliases (
po,dp,svc,no,cm,sts,ds,ks,hr, …) and correct precedence - corepodswins overpods.metrics.k8s.io. Discovered short names also work for custom resources, such as:mdfor MachineDeployments. Exact aliases appear before fuzzy resource matches. Resource names and built-in aliases take priority over discovered short names. Shared short names use group priority, then alphabetical group and resource order. User aliases override discovered aliases. Sofka can connect when it cannot read one API group. Examples: the extension API server is down, or it sends anapiVersionthat is notv1. Sofka does not load that group. It shows a warning at startup and a flash on the first screen.:infoshows the group and the reason. -
Live watch of any kind through
kube::runtime::watcher, streamed into an in-memory store. Watch requests use uncompressed responses to avoid gzip stream errors. List requests retain gzip compression. -
Curated columns for common kinds (pods, deployments, replicasets, statefulsets, daemonsets, services, nodes, namespaces, configmaps, secrets, jobs, cronjobs, PVC/PV, ingresses, endpoints, CustomResourceDefinitions), with a NAME/AGE fallback for everything else. STATUS columns use a fixed width of 26 characters, or 27 for Nodes, so status changes do not move adjacent columns. A configured column width takes priority. Column widths use the full filtered list so vertical scrolling does not move the columns. Node ROLES combines
node-role.kubernetes.io/labels with the legacykubernetes.io/rolevalue and removes duplicate roles. Node STATUS addsSchedulingDisabledwhen the Node is cordoned and keeps its readiness color. -
Event timing - LAST-SEEN shows the most recent reported occurrence for core and events.k8s.io Events. It advances with time and sorts by occurrence timestamp. AGE continues to show object creation age.
-
Service endpoints include ExternalName targets, configured external IPs, load balancer addresses, and NodePort values such as
80:30080/TCP. -
Pod health shows init progress and failure reasons, Pod reasons such as
Evicted, scheduling gates, and termination signals or exit codes. Init progress appears after the kubelet reports init state. Until then, the table keeps the Pod phase or reason, includingSchedulingGated. Normal init containers count toward RESTARTS during initialization, but not READY. Native sidecars count toward READY and RESTARTS. Their failures remain visible after initialization, without adding restarts from completed normal init containers. Application waiting and termination reasons take precedence after initialization. A blocked readiness gate gives a Running pod warning colors even when all containers are ready. Failure reasons use red rows and status text, including init failures and theLostPVC state. -
Horizontal scrolling - Left and Right move the table by five text positions. NAME and NAMESPACE stay fixed. Other columns keep their widths while you scroll. Arrows in the title show where more content is available. When all columns fit, Left and Right do nothing.
-
Custom views - define columns for any resource in the config file. Select and order built-in columns, live CPU/MEM usage, pod request and limit totals, and utilization percentages. Metric columns support numeric sorting, structured filters, and threshold colors. Custom text path columns support
format = "image-tag"to show image tags, with registry ports and digests handled separately. An unknown custom resource picks up its CRDadditionalPrinterColumnsautomatically.wtoggles wide-only columns (kubectl-o wide), including node labels. Add@<namespace>to a view key to select columns for one namespace. See Views and thresholds. -
Drill-down navigation with a breadcrumb stack: workload/service → pods, cronjob → its jobs, node → its pods, pod → containers, namespace → re-scope, CRD → its custom resources.
escgoes back. Workload pod selection includes bothmatchLabelsandmatchExpressions. Drill-down, logs, Explain, and diagnostic bundles apply all requirements, includingIn,NotIn,Exists, andDoesNotExist. Services use their plain label map. -
Resource cycling (
Tab/Shift-Tab) - browse pods → services → deployments → statefulsets → daemonsets → secrets → configmaps → ingresses → PVCs, wrapping in either direction without configuration. Keeps the current namespace (including all namespaces), skips kinds absent from API discovery, and follows the active workspace's views when one is open.[/]remain view history. -
Command palette (
:) - fuzzy search over the full resource catalog, your saved bookmarks and workspaces, and the built-in commands (ctx,helm,pulse,xray,explain,timeline,gitops,adjacent,can-i,journal,debug,debug-clean,bundle,bundle-save,snapshot,snapshots,diff,events,pf,notify,find,vlogs,rightsize,fleet,skin,reload,config,info).:and?open the palette and help from every navigation screen, then close back to the screen where they were opened. -
Cross-context resource navigation -
:pods @production-cluster defaultswitches context, resource, and namespace together without changing kubeconfig'scurrent-context. Context names after@fuzzy-complete: Tab/Shift-Tab select a suggestion and Enter opens it. Omit the namespace to use the target context's remembered or default namespace. Namespace completion after@contextis not provided. -
Help scrolling (
?) - browse all bindings, including plugins, bookmarks, and workspaces.j/kand↑/↓scroll one line.ctrl-f,PgDn, andspacemove forward one page;ctrl-bandPgUpmove back one page. Each page uses the visible content height.g/Homego to the top;G/Endgo to the bottom./filters the bindings and resets the scroll position.escclears the filter first, then closes help.qor?closes help and returns to the previous screen. -
Filtering (
/) with matched-character highlighting: fuzzy text,"text"contiguous match,/re/regular expression (both case-insensitive),!textinverse match (also!"text"and!/re/),-l/-flabel and field selectors (evaluated server-side on ⏎), and typed column comparisons (status=CrashLoopBackOff,cpu>500m,memory>1Gi,restarts>=5,age<2h). Structured terms AND together with spaces or&&;||combines alternatives, parentheses group expressions, and!(...)negates a group. Quote values containing spaces. Selectors survive refresh, namespace changes, drill-down, and view history. The title shows local, server-side, mixed, or pending evaluation;/edits and Esc clears. Palette queries combine scope and filtering::pods -n prod --context west /-l app=api status=Running. See filter grammar and selectors. -
Toggle faults (
Ctrl+Z, pods only) shows pending, failed, unknown, terminating, and running pods that are not ready. Completed pods are hidden. The table title shows[faults]while the filter is on. It works with the text filter and current namespace or drill scope. PressCtrl+Zagain to turn it off. The setting stays on for pod views during the session and does not filter other resource types. ConfiguredCtrl+Zbookmark, workspace, and matching plugin actions take precedence. Live updates keep the selected pod selected. If it leaves the list or its UID changes, selection is cleared. -
Global fuzzy find (
:find <text>) - search object names across the common kinds (workloads, pods, services, config, ingresses, jobs, storage, nodes, namespaces, Flux objects) in every namespace at once, concurrently. Results rank by fuzzy score,⏎jumps to the object. When a kind can't be listed (RBAC), the result says it's incomplete instead of pretending otherwise. -
Multiselect (
space) for bulk delete/kill/suspend/resume/reconcile. -
Copy to clipboard -
ccopies the selected resource's name;Yopens a field picker over the selected row's displayed columns (full values, never the width-truncated cell text) - type to match a column name or its value (an IP, an image, a node),⏎copies it. Falls back to OSC 52 on remote terminals without a local clipboard tool. -
RBAC-aware palette browse - the empty
:list hides kinds you cannotlist. An explicit search checks the full discovery catalog, because some delegated authorizers return incomplete rule reviews. -
Namespace switcher (
n) with pinned favourites (★) and per-context session recents (·) above the rest, plus a context switcher (:ctx) that lists contexts from the default kubeconfig and from any extra file or directory of kubeconfigs added with:kubeconfig, showing each context's cluster, server, namespace, and source file. Same-named contexts in different kubeconfigs stay distinct (prod@work), down to their remembered namespace. In the resource table,1to9select the first nine configured favourites in fixed configuration order. The picker shows these shortcuts beside favourites. Unconfigured slots do nothing.0selects all namespaces. The last namespace picked in each cluster is remembered across restarts (<state-dir>/namespaces.toml);-n/-Aoverride it for a session. -
Default sort -
[views."*"].sortsets a global initial sort, with resource-specific overrides. Sort choices are saved per kind by default. Setremember_sort = falseto make user sort changes temporary. -
Configurable key bindings - change or disable built-in keyboard actions under
[keys]. Shared navigation settings and mode overrides keep text input separate from navigation. Help and key hints show the effective bindings. Changes support:reloadand cluster/context overrides. Invalid bindings keep the previous keymap. Legacy palette settings are migrated with a config backup; managed files produce a warning and use the converted keys in memory. See Configure key bindings. -
Mouse support - the wheel scrolls every view (one notch is three steps of that view's own up/down), clicking a row selects it, clicking a column header sorts by it (click again to flip). Document views (YAML/describe, diff, events, logs, help) release the mouse automatically so click-drag selects text natively; the wheel still scrolls them in terminals that translate it to arrow keys in the alternate screen (kitty, Ghostty, iTerm2, ...). Set
mouse = falseto keep the terminal's native mouse behavior everywhere. sofka also releases the mouse while a suspended command (kubectl exec,$EDITOR) runs. -
Compact mode (
ctrl-e) - collapse the seven-line header and the footer into one info line (kind · count · namespace · context, with a flash and the live indicator), so a tiled pane is almost all table.
- Live CPU and MEM columns for pods and nodes from the metrics API, colored
on unusual values. Nodes also get %CPU and %MEM of allocatable
(
status.allocatable- the pool the scheduler hands out), colored by theutilizationthresholds and sortable, so "which node is full" is one glance and oneS. The container picker shows per-container CPU and memory, usage as a percent of request and of limit (-marks an unset one), and the pod QoS class. Memory quantities use Kubernetes units, including decimalk,P, andE, and binaryPiandEi, in metrics and filters. Fractional bytes round up to the next whole byte. Missing samples show-and do not match numeric CPU or memory filters. Measured zero shows0m,0Mi, or0%. Missing metric values sort before measured values in ascending order and after them in descending order. All of it degrades cleanly when metrics-server isn't installed. - Configurable thresholds for the RESTARTS/CPU/MEM/request-limit coloring, globally and per resource and per context. See Views and thresholds.
- Workload health at a glance - Deployments, StatefulSets, DaemonSets, and
ReplicaSets carry a STATUS column derived from their replica counts and
conditions (
Ready,Progressing,Degraded,Unavailable,Stalled,ScaledDown,Terminating), and the whole row is tinted by it - so a workload whose pods are crashing or whose desired replicas aren't met reads red/peach in the list, like k9s, instead of looking uniformly healthy. - Job execution status distinguishes pending, running, suspended, failed, completing, completed, and terminating jobs. Failed jobs use the error color even when no pod is active.
- Storage deletion status shows
Terminatingfor PVs and PVCs after deletion starts, including when a storage protection finalizer keeps the object in the API. - Explain-unhealthy view (
X/:explain) - a deterministic, evidence-based explanation of why the selection is unhealthy: rollout state, degraded conditions, blocking pods and their container failure reasons (ImagePullBackOff, CrashLoopBackOff, OOMKilled, unschedulable, failed probes), and recent Warning events. No AI, no external service.⏎,E, orljumps from a finding to the pod, its events, or its logs. After opening evidence,escreturns to Explain before anotherescreturns to the table. Opening the view or pressingrreads the selected resource from the API before gathering its evidence. A failed read or a changed UID produces a warning instead of findings from an old snapshot. Only the latest requested report can update the findings. Closing the view withescorqcancels pending results and clears the report progress message. Navigation to a target resource or a palette destination also cancels pending results. Temporary Events and Logs views keep the parent report active. New findings update that report without changing the evidence view. Refresh keeps the previous findings until new results arrive. - Session-local timeline (
T/:timeline) - a per-object timestamped log of every state change the watch saw: generation bumps, replica and readiness changes, pod phase, restarts, waiting reasons, condition flips. Computed from the watch stream, bounded, never written to disk. - Pulse dashboard (
:pulse) - cluster-health tiles, refreshed every 5s. - Xray tree (
:xray) - a hierarchical view from the current kind down through owner references to pods and containers. - Adjacent view (
u/:adjacent) - one hop in every direction from the selection: its owners, the objects it owns, the objects its spec names (a pod's node, claims, ConfigMaps, Secrets; a claim's classes and volume), and the objects whose specs name it (the pods mounting a claim, the claims using a class).⏎opens one in its regular view,y/dshow its YAML or describe. Relations are data: a built-in table for core kinds, extended per CRD with[[views."…".refs]]andchildren. Reverse lookups stay in the row's namespace unless the rule sayscluster. Presscin this view to discover direct children of a namespaced custom resource with a UID, including resources with no configured child kinds. Wait for the initial adjacent lookup to finish first. The search uses API discovery from the current cluster connection. It selects namespaced resources that support listing, excludes subresources, and selects one API version per resource. It searches only the source namespace and matches owner UIDs, not names or labels. Results are added to the view as pages arrive.⏎opens a result. The initial lookup and Enter action on the resource table stay the same. Each search permits four concurrent requests, 200 objects per page, at most 200 list requests and 20,000 objects checked, five seconds per request, and 30 seconds in total. Objects with other owners count towards the object limit. Access denial, request errors, timeouts, skipped API discovery, and search limits mark the search as incomplete. Results already found remain available. The search status stays above the results. Leaving the view, opening an overlay, refreshing, or changing the source or context cancels the search. Late replies are ignored.cstarts another search;rrepeats the initial adjacent lookup. This action does not search across namespaces, follow descendants recursively, or start background watches. - Watch notifications (
:notify) - toggle a notification on the selected object and Sophie watches it for you. See Notifications.
- Flux CD controls (
t) - a suspend/resume/reconcile-now menu built on native Kubernetes API patches, for Kustomizations, HelmReleases, git/helm/oci repositories, buckets, image automation, and notification alerts and receivers. Nofluxbinary needed. Works with bulk multiselect.⏎on a HelmRelease opens the revision history of the Helm release it manages (resolved the way helm-controller composesreleaseName/storageNamespace):⏎shows a revision's values,ythe rendered manifest,dthe NOTES,rrolls back. - Argo CD controls (
t) - a suspend/resume/sync-now menu for ArgoCD Applications, and a suspend/resume menu for ApplicationSets, built on native Kubernetes API patches. Suspend removesspec.syncPolicy.automatedand stashes the original value (includingprune/selfHeal/allowEmpty) as a base64 annotation so resume restores it exactly; ApplicationSet suspend setsapplicationsSynctocreate-only(nononemode exists) and stashes the original value the same way. Sync-now patches the top-leveloperationfield. Noargocdbinary needed. Works with bulk multiselect. - GitOps view (
:gitops/:flux) - the Flux ownership and reconciliation chain for the selection: the owning Kustomization/HelmRelease, its source (GitRepository/OCIRepository/HelmRepository) with applied and latest revision, thedependsOnedges, and ready status. Each item is a finding you can⏎into. Opening the view or pressingrreads the original resource again, then follows its current owner labels, source, and dependencies. A missing or replaced resource produces a warning. These reads requiregetaccess. Only the latest requested report can update the findings. Closing the view withescorqcancels pending results and clears the report progress message. Navigation to a target resource or a palette destination also cancels pending results. - Native Helm inspector (
:helm/:hm) - sofka decodes Helm's release storage Secrets directly (double base64 → gunzip → JSON, same as Helm) and lists one row per release at its latest revision, likehelm list.⏎opens the full revision history (helm history); on a revision,⏎shows user-supplied values,ythe rendered manifest,dthe NOTES.txt.rrolls back andctrl-duninstalls - those two shell out to the realhelmbinary, all the inspection is native. UPDATED advances with the clock in both the release list and revision history. The table keeps the deployment timestamp in its row cache, so clock updates do not decode the release again. - Managed-resource mutation warnings - before you edit, delete, scale, or otherwise change an object Flux (or another controller) owns, sofka tells you the next reconcile will revert it or recreate it. Fix the source instead of fighting the controller.
- CronJob controls (
t) - trigger now (creates a Job from the jobTemplate, likekubectl create job --from), suspend, resume. - Background port-forwards (
f/Fto start,:pfto manage) plus saved forwards that show up in:pfeven while stopped, with optional autostart. Pressingfon a pod or service opens a picker listing the manifest's declared ports; select one to forward immediately, or choose "Custom…" for manualLOCAL:REMOTEinput. Active forwards show a teal●in a dedicated indicator column next to the row name. See Saved forwards. - File transfer (
ton a pod, ortin the container picker for one container) - download from or upload to a pod viakubectl cp, off-thread with a completion flash. Uploads are gated by thetransferguardrail and read-only mode. - PVC explore (
xon a PVC, or:pvc-explore) - a two-pane browser over a volume's contents, withsfor a shell inside it. See PVC explore. - Ephemeral debug containers and node debug pods (
:debug). See Debug containers and pods. - Logs (
l) - combined logs for marked pods, per-container on a pod, or aggregated across all matching pods on a workload/service, with filtering, previous-container logs, and configurable tail/buffer/lookback. If a container is waiting to start, sofka retries until its logs are available. sofka parses ANSI color from the source app and maps it onto the active skin instead of printing literal escapes. See Log controls. - VictoriaLogs integration (
L/:vlogs) - log history from a VictoriaLogs backend for a pod, container, workload, service, or whole namespace, covering restarted and deleted pods. Zero config: sofka finds the service in-cluster and reaches it through the API-server proxy. See Providers. - Right-sizing (
:rightsize) - estimate right-sized requests from past usage in a Prometheus or VictoriaMetrics backend, with a patch preview. Never mutates. See Providers. - Fleet dashboard (
:fleet) - an opt-in health summary across contexts, side by side. Contexts come from config orspacein the:ctxswitcher. See Providers. - YAML view (
y), describe (d, viakubectl), events (:events/E, filtered by UID when available), and diff (:diff), withctrl-f/ctrl-b(orPgDn/PgUp) paging through each document. - Diff on GitOps clusters -
:diffshows a unified diff of the live object against itslast-applied-configuration. When that annotation is missing - as it is for every Flux- or Helm-managed object, which nothing everkubectl applys - sofka diffs against the previous revision this session's watch saw, so "what just changed?" has an answer. The last revision of up to 256 changed objects is kept in memory.
In the describe view, r turns automatic refresh on or off. Refresh is off
when the view opens. When on, it runs kubectl describe immediately and then
5 seconds after each result. This updates the full document, including events.
The resource, scroll position, and search stay the same. Refresh stops when
you leave the view or a request fails. A failed request keeps the last result.
A PersistentVolumeClaim has no API that returns its contents: the only way to
see what is on a volume is from inside a pod that mounts it. x on a PVC row
(or :pvc-explore) does that for you and puts the result on screen as a
two-pane file browser - your local filesystem on the left, the volume on the
right - so a download or an upload is one keystroke rather than a hand-written
kubectl cp path.
- It uses a pod that is already there. sofka looks for a running pod in the
claim's namespace that mounts it, preferring one with a writable mount, and
execs into that container at its
mountPath. Nothing is created, so this works in read-only mode. - Otherwise it offers a helper pod. When nothing mounts the claim - the
common case for a volume you are trying to inspect because its workload is
scaled to zero - sofka asks before creating a short-lived pod that mounts it
at
/pvc. That is a write: it is blocked in read-only mode, matches thepvc-exploreguardrail action, and always confirms, naming the image and the namespace. The helper carries both asleepandactiveDeadlineSeconds, so it expires on its own even if sofka never gets to delete it, and closing the browser - or quitting sofka - deletes it immediately.:pvc-cleanremoves any a crashed session left behind: it sweeps the current namespace, or every namespace when the view is across all of them, requiring the name prefix, both of the labels sofka sets, and the annotation naming the claim, and skipping the pod your own open browser is using. None of that evidence is unforgeable - anything sofka writes on creation, anything else can write too- so it is there to make an accidental match essentially impossible, not as
a permission check; the confirmation, the guardrail and read-only mode are
what bound a deliberate one. It cannot tell a leftover from a pod another session is browsing
through right now, so the confirmation says so. Deleting pods is a mutation
like any other: blocked in read-only mode, matched by the
pvc-exploreguardrail, recorded in:journal.
- so it is there to make an accidental match essentially impossible, not as
a permission check; the confirmation, the guardrail and read-only mode are
what bound a deliberate one. It cannot tell a leftover from a pod another session is browsing
through right now, so the confirmation says so. Deleting pods is a mutation
like any other: blocked in read-only mode, matched by the
- Navigation is confined to the mount.
⌫stops at the mount point, and every listing verifies withpwd -Pthat it actually landed inside the volume - so a symlink on the volume pointing at/is refused rather than quietly dropping you into the serving pod's root. sofka also treats the volume's contents as untrusted: GNUlswrites file names into a pipe unescaped, so a file whose name contains a newline can inject what looks like an extra row, and a symlink target can carry an absolute path. Such a row may still appear as a phantom entry - there is no way to tell it from a real one - but it is contained: entries naming.,.., or anything containing/are discarded, so a forged row can reach neither outside the mount nor outside the directory a download lands in. busyboxls- the default helper image - substitutes?for control characters instead, so there is nothing to forge; such a name lists looking ordinary and fails when you open or copy it. ccopies from the focused pane into the other one - out of the volume when the right pane has the cursor, into it when the left one does. Uploads go throughkubectl cp, are blocked in read-only mode, match thepvc-uploadguardrail action, and are refused up front when the mount isreadOnly. A download that would overwrite a local file confirms first.kubectl cpsplits its arguments on the first:, so a name containing one is refused with an explanation rather than afilespec must match the canonical formatfrom kubectl.sopens a shell at the directory the remote pane is showing (or at the mount point, from the PVC row directly). The exec lands in a real pod, so it passes the sameshellguardrail asson that pod's row - a rule that denies shells in prod is not defeated by reaching the pod through a claim it mounts, and a denied shell is refused before a helper pod is created rather than after.
Listings are read with ls -A -l over kubectl exec, so the pod's image needs
a shell and ls; transfers additionally need tar, as kubectl cp always
does. An entry ls cannot stat still appears, with an unknown size and a
warning, rather than blanking the whole directory. The helper-pod image and
lifetime are configurable:
[pvc_explore]
image = "busybox:1.37" # helper-pod image
ttl = "30m" # how long it lives before deleting itselfOnly a Bound filesystem claim can be browsed: an unbound one has no volume
behind it, and a volumeMode: Block one has no filesystem. A listing is a
point-in-time read, not a watch: r re-reads both panes. Both panes cap one
directory at 5,000 entries - on the volume side by head inside the pod, so a
spool directory is never streamed out in full. An entry nothing could stat
still lists, with ? for its size.
The helper pod runs as whatever user its image defaults to, because reading a
volume's contents generally needs root. It drops all capabilities and sets
allowPrivilegeEscalation: false and seccompProfile: RuntimeDefault, which
satisfies the baseline Pod Security Standard - but not restricted, which
also requires runAsNonRoot. In a namespace enforcing restricted the helper
pod is rejected; browse through a pod that already mounts the claim instead.
- Read-only mode, declarative guardrails, action-aware authorization
(
:can-i), and a session-local action journal (:journal). See Safety.
- Plugins - shell-out commands bound to key chords, scoped per resource, with terminal/popup/background output modes, confirmation and dangerous flags, read-only declarations, rich placeholders, and bulk execution over marked rows. See Plugins.
- Bookmarks - saved navigation commands on a chord and in the palette.
- Workspaces - a named set of views for one task, cycled with
Tab. - Skins - built-in Catppuccin, Gruvbox, Solarized, Nord, Dracula, Tokyo Night, One Dark, Rosé Pine, Rosé Pine Dawn, Monokai, and Flexoki palettes, auto dark/light detection, and per-swatch hex overrides. Every semantic color (row status, severity badges, headers, borders) is derived from the active palette, so one skin change lands everywhere at once.
- Config file (TOML) with per-cluster and per-context overrides and live
:reload. See Configuration.
- Diagnostic bundles (
:bundle,:bundle-save) - a redacted incident bundle for the selection as one Markdown document. See Diagnostic bundles. - Snapshots (
:snapshot,:snapshots) - capture the current table view to text, JSON, or YAML, then browse and open saved captures. See Snapshots. - Runtime diagnostics (
:info, orsofka info) - version and build, config sources, live context/cluster/API server and Kubernetes revision, discovery with warnings for unread API groups, Metrics API status, watch error and reconnect counts, API request latency per class, active skin, loaded plugins and views, and the state/log/snapshot/bundle directories. The connected Kubernetes revision also stays visible in the main header. Identifiers, paths, and counts only, never credentials, tokens, or Secret values. See Runtime diagnostics. - Structured logging (
[logging], orSOFKA_LOG=debug) - sofka's own session log as logfmt lines under the state directory, with every value redacted on the way in and writes off the UI thread. Off by default. See Structured logging.
:sanitizedeletes the pods a namespace has finished with - completed jobs, failed and evicted pods, and optionally the wedged ones. It ships with sofka and needs no runtime onPATH; the adapter is the sofka binary.statesselectsterminal(the default),stuck, orall, based on application container state and Pod phase. Specific table reason labels do not add deletion categories.dry_run=truereports without deleting. It confirms before running, is blocked in read-only mode, and matches guardrails asplugin:sanitize. It never deletes a pod that is terminating, still has a running container, or was replaced since the scan. The scope is the current namespace - all namespaces when the view is.-l/-ffilter terms narrow the scan server-side; a filter it cannot reproduce exactly makes it refuse rather than delete more than the table shows. See Sanitize pods.
- Package discovery reads
plugins/*/plugin.tomlfrom the sofka configuration directory. Packages reload with:reload. - Named commands and key chords start adapters without changes to sofka's source code.
- Validated inputs supply named arguments with types, defaults, choices, and limits.
- JSON reports show text sections and tables in a searchable document.
- Shared execution limits output and concurrency.
It cancels processes on timeout, navigation, or
:plugin-cancel. - Safety controls apply read-only mode, confirmation, and guardrails to plugins. Load-test plugins require a network-load declaration.
- Managed port-forwards supply a local endpoint for a selected pod or service.
- Local checks validate package manifests and reports without a cluster.
Workload STATUS shows Progressing until the controller observes the current
specification and an active rolling update reaches its target. StatefulSet
partitions and OnDelete strategies retain their update semantics. Deployment
READY compares ready replicas with the desired count from the specification.
An active rollout with some ready replicas shows Progressing even when
Available=False. A workload with no ready replicas shows Unavailable. A
failed rollout shows Stalled.