Repository navigation
feat: stored logs, volumes, a guarded shell, backup schedule, secret filters and a reworked UI - #27
Merged
Merged
Conversation
…that clears its hint The Secrets list drops its path and text fields for a Filters menu (project, type, missing a required secret) with removable chips; Create sits at the far right, Delete beside it and copying the selected names is an icon. Each project header collapses its secrets with a chevron. Redeploy and its hint leave the Secrets list for the Project page and the Overview. A redeploy that finishes marks .applied with its exit time, so the needs-redeploy hint clears even when nothing had to be recreated.
…e and a reworked UI Logs: the console follows every running container and keeps its lines for seven days in logs.db on its own volume, with level and stream; the Logs page browses them with nested filters (project and container, level, stream, time), search, live tail and paging back. Volumes: create, browse files (paths and links cannot leave the volume), download a file and delete an unused volume, owners only, with a size bar per volume. Shell: the host shell runs as the unprivileged graphite-ops user, whose sudo allows read-only docker commands only; owners can open a root shell after a confirmation. Both run a bash guard that blocks commands that would take down the VPS or the console or leave the guard, asks before destructive ones, and logs every command to the journal with the login. Backups: the schedule (on or off, every 1 to 168 hours from an hour in UTC, days kept) is set on the page; the late-backup alert follows it. UI: a stats rail with status pills on Alerts, Logs, Backups, Volumes and Admin; action buttons that show saving, saved and failed on themselves; Admin as a member table with an access dialog; collapsible secrets on a project page; descriptions removed; a wider page.
… tooltip The tooltip looked for a point exactly on the pointer's time rounded to the step. History points sit on step boundaries, but live frames carry the millisecond they were sampled, so none ever matched. It now takes the nearest point within half a step, and the newest second no longer falls off the edge.
Every project's archive table, and the requests table, use fixed column widths, so columns line up from card to card; actions sit on the right and narrow screens scroll the table instead of squeezing it. The page and every scrolling container reserve the scrollbar's space, so nothing shifts when a scrollbar appears; the body padding MUI adds when a dialog locks scrolling is cancelled because that space is already reserved.
This was referenced Nov 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Everything asked of the console since #24, in one PR. It includes #25 (chart hover) and #26 (Backups alignment, scrollbar gutter); close those two. Goes with Project-Graphite/platform#46.
Secrets
Redeploy
.appliedwith its exit time, so "needs redeploy" clears even when nothing had to be recreated (for example, secrets imported with the same values). The pill means: the project's env file is newer than its last rollout.Logs
LOGS_KEEP_DAYS) in/logs/logs.db, on its own volume so it stays out of the nightly backup (platform#46), with level and stream. It resumes from the last stored line after a restart.Alerts
Backups
Volumes
Shell
ps,stats,logs,top,images,volume ls,network ls,compose ls,system df); the console creates the user and the rule on first use, checking the rule withvisudo./usr/local/share/graphite/shell-guard.bash) on a DEBUG trap that blocks commands that would take down the VPS or the console (deleting system or Graphite paths, formatting disks, power, stopping docker, ssh or the agent, removing the console's container, volume or the edge network, pruning volumes, firewall flushes, removing users) and attempts to leave the guard (trap, a barebash/sh,su,sudo -i); asks for "yes" before destructive ones (rm -r, docker rm/stop/prune, compose down, systemctl stop, kill, package removal,git reset --hard, overwriting/etc); and logs every command to the journal asgraphite-shellwith the login. The guard is a guard rail for the root shell; the operator user is the boundary.UI
Checks
tsc(server and web),oxlint,npm run build, andtest/alerts.spec.ts,test/backups.spec.ts,test/logstore.spec.ts,test/volumes.spec.ts,test/shell.spec.ts,test/secrets.spec.ts,test/access.spec.ts,test/terminal.spec.ts,test/live.spec.ts,test/history.spec.ts. The guard was also parsed withbash -n, its 59 sample commands classified identically by GNUgrep -E, and run interactively: a blocked command never ran andtrap - DEBUGwas refused. Not run: anything on the VPS (log following, volume browsing, the operator user, sudo), and the pages in a browser.