Files

5.9 KiB
Raw Permalink Blame History

Style guide

Cletus is a professional tool for engineers, analysts and shop-floor teams. A plugin should feel like part of it: calm, dense, exact, and never in the way. Review checks this guide.

1. Principles

  • It just works. Values that can be computed are computed. Nothing waits for a button press that could have been automatic.
  • Model the tool users already know. A CAD screen behaves like the CAD viewers your users use; a forming screen like the forming tools they use. Keep familiar mouse controls and names.
  • Nothing jumps. No layout shift from messages, panels or loading.
  • Professional density. Small type, tight rows, icons. Never big friendly buttons.
  • Simple surface, depth underneath. Show what most people need; put the rest one click away, not on screen.

2. Words

  • Plain words, short sentences. Write for a manufacturing engineer, not a programmer.
  • No internal codes, ids, hashes or stack traces in the interface. A technical detail appears only when it adds to the plain sentence, behind "Details".
  • Errors say what happened and what to do: "The drawing has no tolerance table. Add one, or enter tolerances under Settings." Not "Error 422" or "Something went wrong".
  • Sentence case for labels and buttons ("Save report", not "Save Report").
  • Units always shown beside the value and the input (10 mm).
  • Inexact values carry ~ with the reason on hover. Exact values carry no mark.

3. Theme

  • Use the host's tokens (CSS variables) for every colour. Never hard-code a colour, and never assume the theme is dark.
  • Cletus has three base themes (Amber, which is dark; Dark; Light) and customer variants. Test all three.
  • Engineering and data-dense screens set "theme": "tool". Style controls with the semantic tokens:
    • toggled buttons: --pressed-fill / -text / -border / -indicator
    • primary buttons: --primary-*
    • the active tab: --tab-indicator
    • density: --tool-font (12 px), --tool-row (22 px), --tool-pad (6 px)
  • The accent colour is for thin indicators and small marks. No large filled accent areas.
  • One surface per card. No boxes in boxes.
  • Judge theming by intent (readable, consistent, calm), not by pixels.

4. Layout

  • One job per region.
    • The left rail holds the thing being worked on (a model tree, a document list, jobs).
    • The right rail holds tools, in one collapsible SidePanel that floats over the content and never resizes it. Collapsed, it is a slim icon rail.
    • The top toolbar holds view controls only.
  • A tool's sub-tools appear as a small strip at the top of the content only while that tool is active.
  • A fixed-height status bar shows the selection, progress with cancel, and dismissable failures. Errors never push content around.
  • Floating cards (properties, details) open only when asked for, are movable and closable, and never open on a click or right-click.
  • Nothing a dialog opens may land under it. A setting a dialog needs appears inside that dialog.
  • Settings sit behind a gear at the bottom right, not on screen-switching bars.
  • Icons on every toolbar button (host Icon set), with the name and shortcut in the tooltip.

5. Behaviour

  • Esc stops what is running or closes the innermost thing open (a menu, a live measurement, a panel). It never discards saved work.
  • Every job over a second shows progress, an estimate where possible, and cancel.
  • Instant values compute on selection with "Computing…" in place. A failure is a muted "unavailable" with the reason on hover, not a red banner.
  • Selection is easy to clear: empty click, Esc, × on the status-bar chip, right-click → Clear selection. Hover shows exactly what a click will pick.
  • Right-click shows only a menu. Menus are compact and grouped, like Cletus's own.
  • A resize changes the aspect only. Never re-fit or re-zoom the user's view.
  • Anything placed on the content (pins, labels, annotations) has a visible way to remove it.
  • Files dropped on chat only attach to chat. Your plugin opens a file only when the user chooses "Open in " or drops it on your screen.

6. 3D and 2D viewports

  • Use sdk_viewport for backgrounds and selection so every viewport looks the same.
  • Selection: a soft tint on faces and bodies; the full accent only on selected edges and outlines. Never flood a part in the accent colour.
  • Offer "Set orbit centre here" (trackpads have no middle button).
  • Labels stay inside the viewport and hide or point off-screen when their anchor is hidden. Never draw over panels or toolbars.

7. Chat tools

  • One tool, one operation. No hidden retries or fallbacks inside a tool: fail with the reason and the suggested next call, and let the AI decide.
  • Results are short, factual and stable: the same input gives the same text.
  • Name tools <short plugin name>_<verb>[_<object>] (gauge_check_run).
  • Descriptions say when to use the tool and when not to.

8. Go

  • gofmt, go vet, staticcheck clean. Standard library first.
  • Small packages under internal/, named for what they do. No util, common or helpers.
  • Errors wrap with context (fmt.Errorf("read tolerance table: %w", err)) inside the worker; the message that reaches the user is a plain sentence.
  • Every blocking call takes ctx. No goroutine without a way to stop it.
  • Comments say why, not what. Exported names have doc comments.

9. TypeScript and Svelte

  • Svelte 5 runes. An $effect never reads and writes the same $state.
  • Strict TypeScript. No any without a comment.
  • Components small and named for what they show.
  • No network calls; data comes from your worker or published links.

10. Tests

  • Every tool, service method and ui.* method has a Go test.
  • With screens (a later release): every screen feature gets a browser test that checks it changes what the user sees. Don't compare pixels.
  • Fixtures are synthetic. Reproduce real-world failures with made-up files that have the same shape.