Skip to content

Latest commit

 

History

History
107 lines (93 loc) · 10.8 KB

File metadata and controls

107 lines (93 loc) · 10.8 KB

machud

A beautiful, zero-config terminal system monitor for macOS — a TUI reimagining of Stats (mac-stats.com), built with vue-tui.

machud is opinionated — that's the whole point. Where btop wins on deep configurability, machud wins on beautiful + zero-config: there are no settings, no config files, no layout knobs. The single curated wide-screen dashboard — Apple-Silicon-aware, with one foreground palette that works on light and dark terminal backgrounds — is the product. Want to tune everything yourself? Use btop. machud is the considered default that looks right out of the box and never asks for your password.

Contributing: machud is opinionated by design. Bug reports are welcome; feature PRs opened without a prior, agreed-upon issue are closed directly, and theming/feature/aesthetic changes are generally not accepted. See CONTRIBUTING.md.

Run it

pnpm build          # tsdown → self-contained dist/main.mjs + third-party notices
pnpm start          # run the live dashboard (needs a real TTY)
pnpm dev            # Vite + @vue-tui/vite HMR
pnpm test           # Vitest unit + component render tests
pnpm run check:type # vue-tsc project type check
node dist/main.mjs --once   # render ONE real-data frame to stdout and exit

--once is the verification path: it needs no TTY, prints a single frame with live readings, and doubles as a pipe-friendly snapshot.

Design notes

  • Zero-sudo first. All data comes from unprivileged commands (sysctl, vm_stat, ioreg, pmset, netstat, df, ps) + Node's os. Metrics that need sudo (powermetrics: precise per-cluster freq, GPU watts, fan RPM, die temps) are omitted (D2 — not shown as dead rows), never block startup. See .agents/docs/architecture.md.
  • Never crash, just degrade. sh() resolves "" on failure; each collector returns safe nulls; collectAll() swaps any throwing collector for its empty default.
  • Architecture. src/lib/collectors/* (one file per module) → useMetrics poller → panel components. Full map in .agents/docs/architecture.md — read it before changing data sources or layout.
  • TDD by default. For behavior changes, write or extend the failing verification first, watch it fail when practical, implement the smallest fix, then make the gate green. pnpm verify is the primary harness — it type-checks, builds, black-box-checks --once/--json, drives a PTY, AND runs the Vitest component/unit layer. Extend scripts/verify.mjs for modules / metrics / render / terminal guarantees; add per-panel component render tests under tests/.

Component tests use @vue-tui/testing@0.3.0 to mount real .vue panels through Runtime's production renderer. vitest.config.ts applies only the Vue transform; the terminal-owning @vue-tui/vite plugin remains exclusive to the development server. See D20.

Project Context Records (PCR)

This project follows Project Context Records (PCR) — methodology: https://github.com/hyfdev/project-context-records. PCR keeps the project's durable judgment — the why, the decisions, the intent — so you inherit it instead of re-deriving or re-litigating what's already settled.

When working here:

  • Where records live. Records are in .agents/docs/, one topic per file, cross-linked with relative Markdown links.
    • A README.md there is the map: it routes code areas or hotspots to the exact record or heading, one-line gist per route. Create it when retrieval stops being a glance or one record grows into a long ledger.
  • Read first. Start from the map if present, else scan the folder. Open the records or headings that cover an area before changing or answering for it; if the area has a decision ledger, read it first.
  • Use the strongest durable form. Machine-checkable constraints go in types, tests, lints, or CI; rules that must bind every session go in the agent-instructions file, outside the markers; single-spot rationale goes beside the code with a link; records carry the cross-cutting judgment, intent, and context that must stay prose.
  • Record as you go. Capture context when a decision lands, a trap costs you, a human corrects you, or a human asks — anything true about this project, not durable in a stronger form, and useful beyond the moment.
    • Report what you record so a human can review or vouch it.
    • Records are as public as the repo: keep secrets out, and ask before recording rationale from private context.
  • Write to be acted on. Lead with the current conclusion and where it applies; capture the why — trade-offs, alternatives rejected, known pitfalls. Keep each topic's current truth in one fresh place, updated in place: evolution belongs to git, never to supersede chains.
  • Keep it fresh. Update affected records in the same change that touches their subject.
    • When code and a record disagree, decide which side went stale and fix that side.
    • Back facts with durable evidence — tests, reproducible commands, committed artifacts, stable URLs, commit hashes — not ephemeral paths or one session's output.
  • Provenance. Unstamped text is AI-accumulated: challenge and verify it freely. [VOUCHED @handle YYYY-MM-DD] means the named human explicitly accepted the covered words as current project direction.
    • A vouch is direction, not proof: facts keep needing durable evidence. Don't reopen vouched direction for its own sake — only on new evidence, a changed constraint, or the human's say-so.
    • When evidence argues with vouched direction, record the conflict and surface it to a human; stay inside the direction unless progress becomes impossible. Silence is not an option.
    • Scope: at a non-heading line's end, the stamp covers that line; alone on the first nonblank line below a heading, that section until the next heading of the same or higher level; alone below the document title, the whole file. Never in heading text — link anchors derive from headings.
    • Add a stamp only on explicit instruction. A stamp added by work under review counts only once the named human confirms it; an unchanged stamp on the target branch is inherited project state.
    • The stamp binds the exact covered words. Any edit that changes them — or changes which words the scope covers — removes the stamp until the human re-vouches; a change that leaves the covered words identical keeps it.
    • Legacy stamp forms (undated, before the title, inside a heading) stay valid with their original scope; never move, re-date, or reinterpret one without the human's approval.
  • Decision ledgers. When the human declares that an area records decisions, keep that area's judgments in <area>-decisions.md and register new judgments there.
    • Placement: beside the area's derived document (DESIGN-decisions.md beside DESIGN.md, typically both in the records folder); with no derived document, in the records folder — a map route either way.
    • You may propose opening a ledger; only the human opens one.
    • The register contract, stated at the top of the file: only judgments the human actually expressed enter — a finished implementation, a passed review, resemblance to a reference, or silence is not acceptance. Never invent a rationale: if no reason was given, the entry says so.
    • Record the act of judgment, not the chosen thing's full content — exhaustive detail lives in the area's own document, linked. Edit entries in place; git keeps history.
    • Entries sit under Decided or Open. An Open entry marks a known-undecided question — current behavior is not a choice — with any stopgap and what would settle it. A Decided entry carries:
      • a short stable topic heading — map routes and stamp scopes anchor to it;
      • Ruling: one plain sentence, its force in its own wording — must / never / prefer / default to; no status field;
      • Limits: what it does not govern, what may change without reopening it, what would reopen it — a stopgap is a ruling plus its reopen condition;
      • Why: premises, alternatives compared, rejections — exactly as the human gave them;
      • Source: who expressed it, when, a durable pointer; for "accept the reviewed thing as a whole", pin the thing (commit hash, spec section) instead of transcribing it;
      • the vouch stamp, once the human vouches the entry, alone under the entry's heading — covering the whole entry.
  • Distill when a human reviews. Accumulation is noisy by design; the valve is a human pass, and you draft it.
    • Propose: prune what is contradicted or dead, merge near-duplicates, promote buried context, fix map drift. Unattended, apply this to your own unstamped layer as you go — never the vouched one.
    • Flag: unstamped direction that has become load-bearing, factual claims whose evidence no longer holds, vouches plausibly affected by changes to what they cover.
    • The human decides and vouches.
  • Suggested topics. Draft the missing ones that apply; when an existing doc already covers a topic, enroll it — a map route pointing at it where it lives, held to these same rules — instead of drafting a twin:
    • intent.md — what this is trying to be, for whom, and the non-goals; enroll the README instead if it truly covers them.
    • technology-stack.md — why tools, restrictions, and pins exist; not a manifest dump.
    • architecture.md — units, boundaries, and why the lines are where they are; when structure isn't glanceable.
    • gotchas.md — traps already paid for, each with its why; only real paid lessons.
    • DESIGN.md — only for a visual surface; follow https://github.com/google-labs-code/design.md (records folder by default — the spec fixes no location), enroll it in the map, and suggest wiring its linter into the project's own checks with the file's actual path (e.g. npx @google/design.md lint .agents/docs/DESIGN.md; platform variants in the spec).
    • loop-goal.md — only for an unattended run: the run's contract — goal, boundaries, finish criteria. You may draft it; the run starts only once the human has vouched the whole file (stamp below the title), and a human edit plus re-vouch re-baselines it. Never edit it yourself; if the contract itself blocks progress, stop and surface the conflict rather than stepping outside it.
    • loop-status.md — only for an unattended run: the run's memory — done, in flight, next, blocked — overwritten in place each iteration; its final overwrite is the handover to the returning human (what landed, what to vouch, what to prune, conflicts included). Both loop-* files die after the human's distillation pass over that handover; git keeps them.

Project-specific agent instructions

  • Autonomous work. For hands-off development, follow .agents/docs/autonomous-development-plan.md together with .agents/docs/autonomy.md and the ordered backlog.