Skip to content

feat(ui): redesign penthera ui: Simple mode, setup, 1-bit System look - #63

Merged
danoszz merged 13 commits into
mainfrom
redesign/ui-1bit
Oct 20, 2026
Merged

danoszz merged 13 commits into
mainfrom
redesign/ui-1bit

Conversation

@danoszz

@danoszz danoszz commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Redesigns penthera ui so someone who is not a programmer can use it, and gives it a 1-bit "System" look in ink, paper and #0000ed.

Simple, dark Advanced, light
Simple mode Advanced mode

What changes for people

  • Setup on the first visit: three screens. What Penthera does, Simple or Advanced, then the project folder, an optional URL and a first check. It can be run again from Penthera ▸ Set up….
  • Simple mode (the default): each project opens with one sentence that answers "can I ship?" ("Not ready to ship: 1 critical problem to fix first."), plus one button. Problems are in plain words (Critical, Serious, Worth fixing, Minor). The inspector says what is wrong, how sure Penthera is and what to do, then offers "Fix it for me…". Runs are told in one sentence, with the raw output folded away.
  • Advanced mode: project tabs (Findings, Dependencies, AI tooling, History, Proof) replace the right-hand cards. There is a severity × confidence triage matrix that filters the list, and a step gutter in transcripts.
  • Menu bar: replaces the prompt bar that looked like a chat box. It holds every action with its shortcut, and shows run status, including "Fix 1 of 3 waiting for you". Runs start from a New scan window, which still makes you type back a remote hostname before the run starts.
  • Every fix waits in its own window: pinstriped, over a heavy blur, answered with y, n or q. Closing the window decides nothing.

Look

Tiled windows whose title bar goes solid on the focused one, dither patterns instead of greys, one accent, and Departure Mono (OFL, self-hosted) for chrome. The serif Penthera wordmark is in the menu bar (the P alone below 760px), and the favicon is the P on a blue tile. A halftone field shows how much risk is open: plain paper when nothing is open, dark blobs when something critical is.

Security model

Unchanged. The CSP is the same, there is still no inline script or style, and nothing loads from another host. The font and logos are new static files on the existing allowlist; server.js only gains the font/woff2 type. Report data is still only ever set as text.

Test plan

  • npm test: 902 passed, 21 skipped. This includes new tests for the font and logo files, and that the stylesheet loads nothing from another host.
  • Ran penthera ui --demo in the browser in both modes: setup, the verdict, a problem opened, the fix loop approving all three changes to the end, the triage filter, every Advanced tab, and phone width.
  • A browser contrast audit of every visible text element in 11 states and both themes: all pass WCAG AA. Text on patterns is approximated, and the approval window wasn't in the sweep.
  • First-run screen checked with an empty project.
  • Try it with your real reports: penthera ui --open

Screenshots are regenerated with node scripts/dashboard-screenshots.mjs (headless Chrome, demo data, no network).

Commits carry the AI-Assisted trailer from CONTRIBUTING. They are not signed off (DCO), because that certification is the maintainer's to give. Run git rebase --signoff before merging if you want it.

🤖 Generated with Claude Code

danoszz and others added 7 commits October 20, 2026 13:10
Tiled windows on a dotted desktop with title bars that go solid on the
focused pane, square controls, a blue default button with the classic
outer ring, dither patterns as the only greys, and green retired.
Departure Mono (OFL, self-hosted) for chrome, system sans for prose.
The serif Penthera mark and wordmark replace the pixel P; new favicon.

AI-Assisted: Claude Code with Claude Opus 5.5; designed and wrote the dashboard
  redesign from Daan's brief, references and feedback in one session
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The prompt bar that looked like a chat is gone: runs start from a New
scan dialog (what to run, folder, URL, offline, hostname typed back for
remote targets). A menu bar carries every action with its shortcut and
shows run and egress status, including a diff waiting for you. The
right-hand cards move into project tabs (Findings, Dependencies, AI
tooling, History, Proof); the right window is now only the inspector.
The sidebar lists projects only. Logo: horizontal wordmark in the menu
bar, the P mark below 760px.

AI-Assisted: Claude Code with Claude Opus 5.5; designed and wrote the dashboard
  redesign from Daan's brief, references and feedback in one session
Co-Authored-By: Claude Opus 5.5 <[email protected]>
… window (phase 3)

A first visit opens a three-screen setup: what Penthera does, Simple or
Advanced, then the project folder, an optional URL and a first check.
Simple mode is the default: a verdict sentence with one button, problems
in plain words (Critical, Serious, Worth fixing, Minor), three menus,
a two-choice New scan, an inspector that leads with what is wrong and
what to do, and runs told as one sentence with the raw output folded.
Advanced adds the severity x confidence triage matrix, which filters the
list. Every diff now waits in a pinstriped modal window (y / n / q) and
the transcript has a step gutter.

AI-Assisted: Claude Code with Claude Opus 5.5; designed and wrote the dashboard
  redesign from Daan's brief, references and feedback in one session
Co-Authored-By: Claude Opus 5.5 <[email protected]>
AI-Assisted: Claude Code with Claude Opus 5.5; designed and wrote the dashboard
  redesign from Daan's brief, references and feedback in one session
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The desktop between the windows and the empty inspector show a halftone
field whose density is the open risk: plain paper when nothing is open,
dark blobs when something critical is. Blobs are seeded by the project,
drawn once per size or theme change, never animated. The first-run
screen leads with the serif wordmark and one action, Set up my project.
Tests cover the self-hosted font, the logo files and that the stylesheet
loads nothing from another host.

AI-Assisted: Claude Code with Claude Opus 5.5; designed and wrote the dashboard
  redesign from Daan's brief, references and feedback in one session
Co-Authored-By: Claude Opus 5.5 <[email protected]>
docs/dashboard.md describes setup, Simple and Advanced, the menu bar,
tabs, inspector, approval window, halftone field and the design rules,
with new user stories. Screenshots are regenerated from the demo data by
scripts/dashboard-screenshots.mjs (headless Chrome over CDP, no network).

AI-Assisted: Claude Code with Claude Opus 5.5; designed and wrote the dashboard
  redesign from Daan's brief, references and feedback in one session
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Comment thread scripts/dashboard-screenshots.mjs Fixed
danoszz and others added 3 commits October 20, 2026 13:13
…creenshots

The theme and saved preferences were pasted into evaluated source with
JSON.stringify (CodeQL js/bad-code-sanitization). They now go through
Runtime.callFunctionOn as arguments, so no data becomes code. The theme
is also restricted to light or dark.

AI-Assisted: Claude Code with Claude Opus 5.5; fixed the CodeQL finding on PR #63
Co-Authored-By: Claude Opus 5.5 <[email protected]>
danoszz and others added 2 commits October 20, 2026 17:23
… diff-bound approvals into the redesign

main (#70, #71) moved the dashboard to a bearer session in the URL fragment
and sessionStorage, a fetch-based run stream, SHA-256-bound approvals and
cut-diff acknowledgement, in files the redesign had rewritten. Resolved by
keeping the redesigned files and porting each change into them:

- app.js: signIn() before the first API call.
- center.js: the run stream uses api.stream; Apply (button, y, or y from
  the transcript) sends diffSha256 of the diff as shown; a cut diff shows
  the warning and needs the box ticked before Apply or y works.
- panels.js, menubar.js: report downloads go through api.download, since a
  plain link cannot carry the session header (it now gets a 401).
- right.js: session wording in Settings.
- tests/ui.test.js: static files need no session now; the font and logo
  test checks type and content instead.
- docs/dashboard.md: the cut-diff and SHA-256 rules move into the approval
  window paragraph; reopening a run points at the menu bar and History.
- scripts/dashboard-screenshots.mjs: the #t= link, and globalThis for page
  globals (new lint step).

AI-Assisted: Claude Code with Claude Opus 5.5; resolved the merge conflicts
  and ported main's session and approval changes into the redesign
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@danoszz
danoszz merged commit 2002718 into main Oct 20, 2026
17 checks passed
@danoszz
danoszz deleted the redesign/ui-1bit branch October 20, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants