Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
6592c95
fix(ui): Escape closes the innermost thing, and a closed dropdown is …
hans-fischer Oct 22, 2026
c45cf0c
test(alerting): the service proxy poller's test waits for three polls
hans-fischer Oct 22, 2026
008b159
test(ui): the connection dot's click test leaves the navigator's own …
hans-fischer Oct 22, 2026
ad957bb
fix(ui): close the drawer at once on a click below the rows
hans-fischer Oct 22, 2026
db5a47e
fix(ui): connect from a welcome row at the click's release
hans-fischer Oct 22, 2026
2e404e0
feat(ui): a failed connect's error page with the connect's stages (D-…
hans-fischer Oct 22, 2026
db73e2c
test(ui): a welcome row's single connect under the page D-114 derives
hans-fischer Oct 22, 2026
daa476b
fix(engine): a cancelled connect and one left in the background are n…
hans-fischer Oct 22, 2026
815de06
feat(ui): copy a masked Secret value without showing it
hans-fischer Oct 22, 2026
6025bd2
feat(ui): a revealed Secret value Show cut copies whole by its icon
hans-fischer Oct 22, 2026
42c2d12
fix(ui): a dialog's Context row draws the source label grey
hans-fischer Oct 22, 2026
7f1e26f
fix(engine): a dock tab shown again opens the minimised dock
hans-fischer Oct 22, 2026
c1f90ec
fix(ui): Move Tab Left and Right move the dock's tab where the keys are
hans-fischer Oct 22, 2026
27bf01f
fix(ui): Move Tab's keys follow a clicked dock tab's focus
hans-fischer Oct 22, 2026
a9f9e8c
fix(engine): a deleted namespace the filter names is read on the name…
hans-fischer Oct 22, 2026
0485ba0
feat(ui): Follow in a logs tab switched by scrolling
hans-fischer Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 5 additions & 3 deletions ROADMAP.md

Large diffs are not rendered by default.

117 changes: 98 additions & 19 deletions docs/developer/architecture.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/developer/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Cogpit and its flags are in [`usage.md`](usage.md).
| `chat.toggle` | `chat_toggle` | ui | `open`? | Shows or hides the built-in agent's chat column at the right edge of Cogpit's window, as ⌘I (Ctrl+I) does. ui_state reports chat: true while it is shown |
| `cluster.alertmanager` | `cluster_alertmanager` | read | `context`? | Returns which Alertmanager a connected cluster's alerts come from (the shown one unless context names another): auto (found among the cluster's Services by its well-known names) or the address namespace/service:port, path prefix and https the user set, whether it is kept in Cogpit's preferences, and what Cogpit knows of it now (state, inUse, detail) |
| `cluster.connect` | `cluster_connect` | ui | `context` | Connects to a context as cluster_contexts lists it and shows it in the window: its most recently used tab, or else its Pods view in the preview tab; the other clusters' tabs stay |
| `cluster.connectLog` | `cluster_connectLog` | read | `context`, `limit`? | Returns a context's connection log. attempts: every connect, reconnect, login, disconnect and interruption kept (7 days, at most 1 MiB per context, also from earlier runs), newest first, each with its kind, start, end, duration (tookMs), outcome (ok, failed, abandoned, cancelled, interrupted for an interruption, whose reconnect is the next attempt; empty and running:true while it runs, empty otherwise when Cogpit stopped first) and lines: a time, a level (INFO, WARN or ERROR), a text, the step it documents (kubeconfig, server, login, tls, proxy, answer, discovery, cache, access, heartbeat, error, plugin) and its duration |
| `cluster.connectLog` | `cluster_connectLog` | read | `context`, `limit`? | Returns a context's connection log. attempts: every connect, reconnect, login, disconnect and interruption kept (7 days, at most 1 MiB per context, also from earlier runs), newest first, each with its kind, start, end, duration (tookMs), outcome (ok, failed, abandoned, cancelled, interrupted for an interruption, whose reconnect is the next attempt; empty and running:true while it runs, empty otherwise when Cogpit stopped first) and lines: a time, a level (INFO, WARN or ERROR), a text, the step it documents (kubeconfig, server, login, tls, proxy, answer, discovery, cache, access, heartbeat, error, plugin) and its duration; a connect's stages too (stages: kubeconfig, login for a credential plugin, dns, tcp, tls, api, each with its result ok, failed, notReached, skipped or cancelled, its text and tookMs: the names looked up and their addresses, the address and port dialled, or the proxy's, the TLS handshake and the API server's answer) |
| `cluster.contexts` | `cluster_contexts` | read | | Lists the kubeconfig contexts Cogpit can connect to (name, cluster, user, default namespace, server, whether it is the kubeconfig's current context) |
| `cluster.disconnect` | `cluster_disconnect` | ui | `context`? | Closes Cogpit's connection to a connected cluster (ui_state's connections; context, else the cluster the window shows), or cancels a connect under way, the shown cluster's or one restoring the last session (the window's Cancel Connecting): a credential plugin the connect waits for (connection.waitingForLogin, a browser login) is ended at once, and the cluster is not connected |
| `cluster.integrations.answer` | `cluster_integrations_answer` | ui (GUI only) | `context`?, `integrations`?, `saveAsDefault`? | Answers the window's question about a cluster's integrations (ui_state's integrationsQuestion), as its Apply button does (and the warning's Yes of Don't use integrations, with every one off): starting from what applies now (the question's ticks; none for a cluster the window does not ask about), the integrations named are switched on or off and the result is the cluster's own choice; with saveAsDefault it is also the default for new clusters |
Expand Down Expand Up @@ -220,13 +220,13 @@ Cogpit and its flags are in [`usage.md`](usage.md).
| `ui.setStatusFilter` | `ui_setStatusFilter` | ui | `states`? | Sets the status filter of the open view, as the window's states menu beside the namespace filter does (Cogpit's addition; Lens has none): only the rows that carry the given states are shown, in the table, view_rows, select all and the CSV export. view_rows lists the states the rows carry (stateChoices, with counts) |
| `ui.sort` | `ui_sort` | ui | `column`, `desc`? | Sorts the open view by a column id (name, namespace, age, ... as kinds_list reports them), ascending unless desc is true |
| `ui.sortDrawerTable` | `ui_sortDrawerTable` | ui | `column`, `desc`?, `section`? | Sorts a table in the detail drawer by a column, as a click on the column's title does: the Pods of a node, Deployment, Replica Set, Stateful Set, Daemon Set, Job or Cron Job by name, node, namespace, ready, cpu, memory, status or any other of its columns, ascending unless desc is true |
| `ui.state` | `ui_state` | read | | Returns what the user sees: the connected context and its connection state (tlsUnchecked when the connection does not check the server's certificate), who Cogpit is logged in as there (user: username and groups with source apiServer when the API server confirmed them at the connect, source kubeconfig with a reason when it did not and username is only the kubeconfig's user entry's name, source lastSeen with lastSeen while the cluster is not connected; absent for the demo cluster and a context never confirmed), its Kubernetes version (clusterVersion: the API server's version as its connect read it, its minor and the minor's upstream support from the Kubernetes release table built into this Cogpit, upstream's dates only: released, maintenanceFrom, endOfLife, estimated for a minor newer than the table (tableNewest, tableFetched), state supported, maintenance, endOfLife or unknown as of now, daysLeft; view_rows' tips say each node's kubelet support and version skew), the open view (kind key), the namespace filter, the search text and its toggles (filterOptions: matchCase, regex; filterError when its regular expression is invalid), the status filter (states; view_rows lists the states offered), the sort order, the selected objects (selected: the shown view's; every view keeps its own, which comes back when the view is shown again and is not listed meanwhile), the object in the detail drawer and the order of its sortable tables by title (drawerSort: a node's or a workload's Pods, ui_sortDrawerTable), the tab bar's tabs (tabs and activeTab: each tab's id, context, view, title, preview or fixed, its own filter and selection, and its history), the dock tabs, how many rows the view shows of how many objects, for a pod's or node's drawer the time range and variant of each metrics chart (drawerCharts) and the metrics providers' status line (drawerMetricsProviders: Prometheus and the Metrics Server, answering or not, what each serves), the hotbar of pinned clusters as hotbar_list returns it, one list of clusters top to bottom (each tile's displayName is the name the window shows: the display name set, else the part of the context's name after its last @; commands take the context), and timeFormat, the Go layouts of a date and a time of day that the drawn texts (view_rows, resources_list, object_get's sections) write absolute times in, in the Preferences' time zone; the window's layout (navigatorHidden, dockOpen, chat) and update, the newer release the updater holds for the user (available, version) |
| `ui.state` | `ui_state` | read | | Returns what the user sees: the connected context and its connection state (tlsUnchecked when the connection does not check the server's certificate; after a failed connect state error, error its cause in a sentence and connectFailure the page the window shows for it: the context, when, and the connect's stages kubeconfig, login, dns, tcp, tls and api, each with its result and text; welcome is set while the welcome page shows instead), who Cogpit is logged in as there (user: username and groups with source apiServer when the API server confirmed them at the connect, source kubeconfig with a reason when it did not and username is only the kubeconfig's user entry's name, source lastSeen with lastSeen while the cluster is not connected; absent for the demo cluster and a context never confirmed), its Kubernetes version (clusterVersion: the API server's version as its connect read it, its minor and the minor's upstream support from the Kubernetes release table built into this Cogpit, upstream's dates only: released, maintenanceFrom, endOfLife, estimated for a minor newer than the table (tableNewest, tableFetched), state supported, maintenance, endOfLife or unknown as of now, daysLeft; view_rows' tips say each node's kubelet support and version skew), the open view (kind key), the namespace filter, the search text and its toggles (filterOptions: matchCase, regex; filterError when its regular expression is invalid), the status filter (states; view_rows lists the states offered), the sort order, the selected objects (selected: the shown view's; every view keeps its own, which comes back when the view is shown again and is not listed meanwhile), the object in the detail drawer and the order of its sortable tables by title (drawerSort: a node's or a workload's Pods, ui_sortDrawerTable), the tab bar's tabs (tabs and activeTab: each tab's id, context, view, title, preview or fixed, its own filter and selection, and its history), the dock tabs, how many rows the view shows of how many objects, for a pod's or node's drawer the time range and variant of each metrics chart (drawerCharts) and the metrics providers' status line (drawerMetricsProviders: Prometheus and the Metrics Server, answering or not, what each serves), the hotbar of pinned clusters as hotbar_list returns it, one list of clusters top to bottom (each tile's displayName is the name the window shows: the display name set, else the part of the context's name after its last @; commands take the context), and timeFormat, the Go layouts of a date and a time of day that the drawn texts (view_rows, resources_list, object_get's sections) write absolute times in, in the Preferences' time zone; the window's layout (navigatorHidden, dockOpen, chat) and update, the newer release the updater holds for the user (available, version) |
| `ui.tab.back` | `ui_tab_back` | ui | | Goes back to the view the active tab showed before (its history: views opened in the preview tab, ui_navigate to another kind) |
| `ui.tab.close` | `ui_tab_close` | ui | `id`? | Closes the active tab (or the tab named by id) |
| `ui.tab.forward` | `ui_tab_forward` | ui | | Goes forward again in the active tab's history, after ui_tab_back |
| `ui.tab.move` | `ui_tab_move` | ui | `id`?, `index` | Moves a tab of the tab bar (the active one without id) to another place among the tabs the bar shows, as dragging it there does: index 1 is the first |
| `ui.tab.moveLeft` | `ui_tab_moveLeft` | ui | | Moves the active tab one place to the left in the tab bar, as ui_tab_move does |
| `ui.tab.moveRight` | `ui_tab_moveRight` | ui | | Moves the active tab one place to the right in the tab bar, as ui_tab_move does |
| `ui.tab.moveLeft` | `ui_tab_moveLeft` | ui | `dock`? | Moves the active tab one place to the left in the tab bar, as ui_tab_move does, or with dock the dock's active tab in the dock, as dock_move does |
| `ui.tab.moveRight` | `ui_tab_moveRight` | ui | `dock`? | Moves the active tab one place to the right in the tab bar, as ui_tab_move does, or with dock the dock's active tab in the dock, as dock_move does |
| `ui.tab.next` | `ui_tab_next` | ui | | Activates the tab right of the active one, the first after the last, as ui_tab_select does |
| `ui.tab.open` | `ui_tab_open` | ui | `fixed`?, `view` | Opens a view of the shown cluster in a tab of the tab bar: in the preview tab (which the next view opened in preview replaces; ui_openView does the same), or with fixed in a new fixed tab that stays until closed |
| `ui.tab.pin` | `ui_tab_pin` | ui | `id`? | Makes the preview tab (or the tab named by id) a fixed tab, as a double click on its title does: the next view opened in preview then opens in a new preview tab |
Expand Down
9 changes: 9 additions & 0 deletions docs/developer/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ malformed-input tests or fuzz targets.
on such a line (2026-10-12).
- Verify every visual change with an offscreen render (Fyne's `test` package) or a screenshot, in
dark and light themes, and attach before/after images to the pull request.
- Escape closes the innermost thing open ([D-116](decisions.md#d-116-escape-closes-the-innermost-thing),
[`escape.go`](../../internal/ui/fyneui/escape.go)): show a Fyne dialog with `sh.showDialog`, never
its own `Show`; show a `widget.PopUp` through `onShown` with what closes it; give a dialog's
fields the types that pass Escape on to the dialog's Cancel (`newFieldEntry`,
`newFieldSelectEntry`, `newFieldCheck`, `newFieldSlider`), never Fyne's plain ones
(`TestEveryDialogTakesEscape` reads the sources for the first two).
- Every dropdown is a `selectField` (`newSelectField`, [`selectfield.go`](../../internal/ui/fyneui/selectfield.go)),
never Fyne's `widget.NewSelect`: it opens over its field, the current entry checked at the
field's place, as a macOS pop-up button (the owner's GW5, 2026-10-20: Fyne's list showed the
Expand All @@ -163,6 +169,9 @@ Kubernetes-Objekten ist immer: Context, Namespace, Objects."
the kind once, the names under each other; in plain text (a title) "Config Map → walk-cm". A
dialog builds its rows with `placeRows` and `objectsRow` ([`objectnames.go`](../../internal/ui/fyneui/objectnames.go)),
never with `kind + " " + name`.
- **A context is named by its id as it is, its source label grey** (the owner's AW7, 2026-10-22:
"aber grau wäre top"): the Context row reads "kind-cogpit [kubernetes_configs/walk-kind.yaml]",
the label in brackets in the kind word's muted colour (`contextValue`, which `placeRows` uses).
- **What a command does beyond its objects is a quick view, never a sentence** (the owner's WF33:
"technisch präzise Schnellansicht"): a row per fact with its own short name ("Removes",
"To revision", "Image"), the value terse, names bold, what is lost bold in the error colour, what
Expand Down
502 changes: 463 additions & 39 deletions docs/developer/decisions.md

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion docs/developer/design-language.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ brackets with end ticks, lowercase labels with a middle dot, a faint perspective

The palettes in [theme.go](../../internal/ui/fyneui/theme.go) replace Solarized (D-22) on this branch.
Dark: stage `#0d121a`, chrome `#0a0e14`, sidebar `#0b0f16`, drawer `#10161f`, overlay `#121925`,
hairline `#1b2330`; text `#d5dde8`, muted `#8592a5` (5.9:1 on the stage); glow blue `#4aa8ff`, cyan
hairline `#1b2330`, a well's or card's edge `#263042`; a field's outline `#3e4f6a`, light `#a1acbc`,
2:1 on every surface a field stands on, since a closed dropdown on a dialog read as the dialog's own
colour (the owner's AW1 of 2026-10-22, [D-104](decisions.md#d-104-dialog-fields-their-hints-and-dropdowns-the-gate-walks-gw2-gw5-gw6)); text `#d5dde8`, muted `#8592a5` (5.9:1 on the stage); glow blue `#4aa8ff`, cyan
`#5ad1e3`, violet `#a48bff`; status mint `#3dd68c`, amber `#f2c14e`, orange `#ff9f5a`, coral `#ff6b74`,
rose `#ee82b8` (Terminating; violet is the agent's), blue `#5ab8ff` (Succeeded). Light keeps the same
roles on white plates with the lights deepened for 4.5:1 text. Every pair still passes
Expand Down
3 changes: 1 addition & 2 deletions docs/developer/ui-threads.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The UI's goroutines

> **Last reviewed:** 2026-10-19 · **Last updated:** 2026-10-22 · **Change:** trivial (`dock.showAddMenu`'s row removed: the dock's "+" menu is gone, its terminal chip dispatches on the main goroutine's tap); trivial (a row for the namespace filter's recheck timer, GW9, D-106); new (the audit before
> **Last reviewed:** 2026-10-19 · **Last updated:** 2026-10-22 · **Change:** trivial (the namespace filter's recheck timer's row removed: EventNamespaces reads the namespaces again, AW11, D-106); trivial (`dock.showAddMenu`'s row removed: the dock's "+" menu is gone, its terminal chip dispatches on the main goroutine's tap); trivial (a row for the namespace filter's recheck timer, GW9, D-106); new (the audit before
> Fyne's thread check is turned off in releases, [D-103](decisions.md#d-103-fynes-thread-check-a-build-parameter-off-in-releases))

Fyne runs every widget on its main goroutine. Code that runs anywhere else (a goroutine, a timer,
Expand Down Expand Up @@ -86,7 +86,6 @@ places of the same kind has one row.
| `fyneui/tablecheck.go` | `tableView.openSelectionMenu` | go | A | `evaluateSelection` (registry, `commandEnabled`) on references cloned on main; the menu built and shown inside `sh.do`. |
| `fyneui/tablecheck.go` | `selectionBar.askReason` | go | A | The registry's label and `commandEnabled` on cloned references; the tooltip set inside `sh.do`. |
| `fyneui/tableview.go` | `tableView.searchChanged` | AfterFunc | A | `sh.dispatch(ui.setFilter)` with the text copied; `done` (`filterBusy`, `syncSearch`) runs through `sh.do`. |
| `fyneui/nsgone.go` | `shell.recheckNamespaces` | AfterFunc | A | The timer's function is only `sh.do(...)`: clearing `nsRecheck` and the next read run on the main goroutine (GW9, D-106). |
| `fyneui/palette.go` | `cmdPalette.load` | go | A | `Registry.Palette` over a cloned state; `containersFor` reads the engine; results applied inside `sh.do`. |
| `fyneui/palette.go` | `shell.runPaletteAction` | go | A | `evaluateActions` and `containersFor` touch the engine only; `runAction` or the toast inside `sh.do`. |
| `fyneui/navigator_sections.go` | `navSections.load` | go | A | `Contexts`; render and the hotbar's marks inside `sh.do`. |
Expand Down
Loading
Loading