Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
7b27f79
feat(desktop): add the core crate and a fixture-driven app window (HA…
roodboi Nov 14, 2026
60d0e01
fix(desktop): read native projects with the native backend and treat …
roodboi Nov 14, 2026
4643e7b
fix(desktop): accept null collections, bound pipe draining by the tim…
roodboi Nov 14, 2026
bc7f004
fix(desktop): show exit-0 services as exited with unknown role, and l…
roodboi Nov 14, 2026
cc2677d
fix(desktop): keep startup failure detail, make Open single-flight, h…
roodboi Nov 14, 2026
9d32d82
fix(desktop): validate the CLI projects payload, show native services…
roodboi Nov 14, 2026
48fb07c
fix(desktop): trust hackd only from a private directory and a same-us…
roodboi Nov 14, 2026
7bd5b48
docs(desktop): correct the native view-only note
roodboi Nov 14, 2026
a1144a7
fix(desktop): clear a failed start only on evidence, and treat any fa…
roodboi Nov 14, 2026
0518c95
fix(desktop): scroll the sidebar project list between the fixed heade…
roodboi Nov 14, 2026
cec136c
Merge remote-tracking branch 'origin/next' into feat/desktop-app-core
roodboi Nov 14, 2026
c814cb0
docs(desktop): render all 15 fixture states in the screenshot boards
roodboi Nov 14, 2026
8366c34
feat(desktop): add the Logs tab (follow, pause, search, service filte…
roodboi Nov 14, 2026
a6c423a
fix(desktop): do not count never-created services (inactive profiles)…
roodboi Nov 14, 2026
f5779ea
fix(desktop): bound log intake and memory, pause on scroll, keep trai…
roodboi Nov 14, 2026
dab34b4
fix(desktop): scroll the detail content below a fixed header
roodboi Nov 14, 2026
da325c7
fix(desktop): never hang dropping a full log stream; free capped line…
roodboi Nov 14, 2026
6bee49a
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
fa6b732
fix(desktop): let any log line expand, including width-clipped ones
roodboi Nov 14, 2026
7d215f3
fix(desktop): follow logs once a stopped project starts
roodboi Nov 14, 2026
408fb6e
fix(desktop): run hack by absolute path found on absolute PATH entrie…
roodboi Nov 14, 2026
c884917
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
4833805
fix(desktop): keep a paused log view on the lines being read while ol…
roodboi Nov 14, 2026
127ac3c
fix(desktop): act only on project roots the user owns
roodboi Nov 14, 2026
39717fa
fix(desktop): read the log list's top row through the production scro…
roodboi Nov 14, 2026
1608e4a
fix(desktop): validate the project root's path chain, marker and conf…
roodboi Nov 14, 2026
89a1af9
fix(desktop): give CLI children a PATH with only absolute entries
roodboi Nov 14, 2026
b7ee630
fix(desktop): require the CLI to select exactly the validated root, a…
roodboi Nov 14, 2026
cce493d
fix(desktop): never hand children an empty PATH
roodboi Nov 14, 2026
7230198
fix(desktop): show Doctor as unknown until it has run
roodboi Nov 14, 2026
6916b86
fix(desktop): clear logs when the selected project has no folder
roodboi Nov 14, 2026
f62a14f
fix(desktop): cap log events before queueing and shrink the queue, bo…
roodboi Nov 14, 2026
45bebd2
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
13b7dec
fix(desktop): bound every queued log event field, not just the messages
roodboi Nov 14, 2026
630d6cb
fix(desktop): on timeout, SIGTERM the CLI's group and wait before SIG…
roodboi Nov 14, 2026
b88cdec
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
f7af68e
fix(desktop): let the CLI own lifecycle timeouts instead of cutting t…
roodboi Nov 14, 2026
3d4ef7e
fix(desktop): reset the log service filter on every project change
roodboi Nov 14, 2026
77ad59c
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
c1dde2b
fix(desktop): never terminate lifecycle commands from the app; warn a…
roodboi Nov 14, 2026
6ea9c3d
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
c24bba2
fix(desktop): build and test on macOS, and add a headless live-state …
roodboi Nov 14, 2026
5bf507b
Merge remote-tracking branch 'origin/next' into feat/desktop-app-core
roodboi Nov 14, 2026
cbc43ef
test(desktop): never count a missing /proc as proof a process exited
roodboi Nov 14, 2026
263d04e
fix(desktop): drain CLI output pipes within bounded memory
roodboi Nov 14, 2026
efd92f8
fix(desktop): retry interrupted pipe reads and report other read fail…
roodboi Nov 14, 2026
e595f00
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
db1d4c6
Merge remote-tracking branch 'origin/next' into HEAD
roodboi Nov 14, 2026
b341b32
fix(desktop): align the minimum toolchain and isolate state-reader tests
roodboi Nov 14, 2026
94c77a7
Merge remote-tracking branch 'origin/feat/desktop-app-core' into HEAD
roodboi Nov 14, 2026
074a519
Merge remote-tracking branch 'origin/feat/desktop-app-core' into feat…
roodboi Nov 14, 2026
1f572e8
fix(desktop): drain log diagnostics and align fixture states
roodboi Nov 14, 2026
66a3896
Merge remote-tracking branch 'origin/feat/desktop-app-logs' into HEAD
roodboi Nov 14, 2026
71376d8
fix(desktop): preserve failure evidence and refuse registry-writing p…
roodboi Nov 14, 2026
ffe35e3
fix(desktop): discard log overflow and preserve failure diagnostics
roodboi Nov 14, 2026
9458275
Merge commit '71376d86baedf6bfb790c5676d039ee3716b11ff' into HEAD
roodboi Nov 14, 2026
d57d36b
fix(desktop): clear overflow count for unavailable projects
roodboi Nov 14, 2026
72ae2a5
fix(desktop): mark stale observations unknown and offer daemon recovery
roodboi Nov 14, 2026
b6eb9e6
Merge commit '72ae2a583496db4ce2449efc48b49749ed1fc2ba' into HEAD
roodboi Nov 14, 2026
d39223e
fix(desktop): detect failed exits across every service replica
roodboi Nov 14, 2026
2e68cef
Merge commit 'd39223e5b352e5e7a81cb28683378948e6a5d13b' into HEAD
roodboi Nov 14, 2026
43a14dc
Merge remote-tracking branch 'origin/next' into HEAD
roodboi Nov 14, 2026
a4d01ec
fix(desktop): bind asynchronous log tails to the selected backend
roodboi Nov 14, 2026
cc60c49
docs(desktop): refresh fixture boards for merged core guidance
roodboi Nov 14, 2026
c81f947
docs(desktop): state the upstream log allocation limit
roodboi Nov 14, 2026
2dd1f19
Merge remote-tracking branch 'origin/next' into HEAD
roodboi Nov 14, 2026
4b16a0e
Merge remote-tracking branch 'origin/next' into HEAD
roodboi Nov 14, 2026
95df616
test(desktop): make the failed Logs fixture agree with the Docker status
roodboi Nov 14, 2026
7934a74
merge: integrate next into the Logs tab
roodboi Nov 15, 2026
5ff6ee6
merge: integrate next into the Logs tab
roodboi Nov 15, 2026
b98f53a
merge: integrate next (#835, #831) into the Logs tab
roodboi Nov 15, 2026
fb6a5ed
fix(desktop): never signal a log stream's process after poll reaped it
roodboi Nov 15, 2026
7ab1542
merge: integrate next (Env tab #818, #802, #860) into the Logs tab
roodboi Nov 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions apps/desktop/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,16 @@ Source: `hack logs --json --path <root> --tail 500` (ndjson, follows by default)
| State / control | Behaviour |
|---|---|
| Follow (default) | Newest at bottom; auto-scroll while at the bottom. |
| Pause | Stops auto-scroll; keeps reading into a ring buffer bounded at 10,000 lines **and** 8 MB; "N new lines" chip. Scrolling up pauses. |
| Pause | Stops auto-scroll; keeps reading into a ring buffer bounded at 10,000 lines **and** 8 MB; "N new lines" chip. Scrolling up pauses; Resume returns to the bottom. No pause timeout or automatic resume at the bottom in this preview. |
| Search | Filters the buffer in place (plain text, case-insensitive), with match count. |
| Service filter | One service at a time: restarts the stream as `hack logs <service>`. `--services` is Loki-only and native rejects it (and `--compose`), so the app never passes either. Multi-select needs R4. |
| Very long lines | Cut at 4 KB on screen with "… (+N KB)", click to expand; `entry.truncated` shown as "truncated by hack". |
| Secrets warning | Fixed note: "Logs are shown as your services print them. Hack does not hide secrets in logs." No copy-all; buffer never written to disk; "Open in terminal" offered. |
| Finished | `end` event on a `--no-follow` read: "End of log" (normal). |
| Follow ended | while following, an `end` event (`eof` from Compose, `closed` from Loki) and exit 0: "Log stream ended" + Reconnect. Not an error. |
| Stream error | `error` event or exit ≠ 0: banner with reason and Reconnect. Docker down: "Docker not reachable". |
| Closed by the app | tab change, project change or pause timeout: the app kills the stream; nothing is shown. |
| Stream error | `error` event or exit ≠ 0: banner with reason and Reconnect. CLI failure envelopes and bounded diagnostic tails provide the reason. Docker failures retain the CLI's wording; a normalized "Docker not reachable" label is deferred. |
| Closed by the app | tab change or project change: the app kills the stream; nothing is shown. |
| Busy stream | The reader continuously consumes stdout. A full bounded event queue discards incoming events and reports a visible skipped-event count; it never waits for UI drain. This bounds app retention, not arbitrary producer-side CLI buffering. |
| Stopped project | Last 200 lines (`--no-follow`), marked "project stopped". |

### Env tab (names only, never values)
Expand Down
35 changes: 29 additions & 6 deletions apps/desktop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ each project's detail as JSON. It runs no action, opens no window and writes
nothing.

An accepted refresh that changes the selected project root or backend clears the
previous log tail, including when Follow is off.
previous log tail, including when Follow is off, and replaces any open Logs stream.

Live reads refresh every two seconds with a matching daemon and retry every ten
seconds when unavailable. Every request has an order token: a read started before
Expand All @@ -85,11 +85,34 @@ engine-down, error / cli-missing, many-projects, stopped / starting, running,
degraded / stopping, failed-start, needs-attention):
[light](screenshots/fixtures-light.png), [dark](screenshots/fixtures-dark.png).

## What v0 does not do yet

Logs and Activity tabs, CPU and memory, Doctor view, onboarding, always-on,
daemon actions and upgrades come in later units. The design and the CLI/daemon
requests they need are in `DESIGN.md` (PR #800).
## Logs tab

`hack logs --json` for the selected project, following by default:
- Pause (reading continues, with an "N new" count), search, and a filter for one service (`hack logs <service>`).
- Click any line to show it in full below the list (long or width-clipped lines); lines over 4 KB show how much is hidden.
- "Log stream ended" and failures are shown distinctly, with Reconnect.
- CLI stderr is drained concurrently with an 8 KB retained tail. A separate 8 KB tail retains non-event stdout, including pretty JSON failure envelopes. Failed exits show the CLI error message or diagnostic tail and a human-readable exit status.
- The buffer holds at most 10,000 lines and 8 MB (service and timestamp included). Messages in valid records are capped at 64 KB; raw records over 1 MiB are replaced by a visible dropped-record marker instead. Memory only: nothing is written to disk and there is no copy-all.
- Scrolling up pauses following; Resume returns to the newest line. Each event's text fields are capped before queueing (log message 64 KB, notice 4 KB, other fields 256 bytes). The 1,024-event queue retains at most about 70 MiB of text. When full, the reader discards incoming events and keeps consuming stdout; the tab shows a cumulative skipped-event count. The CLI does not honor pipe backpressure, so blocking the reader would allow its own output buffer to grow. This bounds app retention, not the CLI's memory under an arbitrarily fast producer.
- Stderr output uses a muted style; only explicit error-level entries use the danger color. Services-tab tail polling stops while Logs is open.
- The app's limits do not bound allocations before the CLI emits a record: the current Compose reader accumulates a complete line before JSON formatting. A single oversized or unterminated service line can therefore grow CLI memory. Bounding that upstream chunk reader is a separate CLI fix; this preview does not claim end-to-end memory safety against arbitrary service output.
- "Copy command" copies the equivalent `hack logs --path … [service]` for a terminal.
- Native projects show the terminal command instead, because native logs are a one-service snapshot.

Fixtures: `--logs-fixture <state>` (`--list-fixtures` lists them). Boards:
[light](screenshots/logs-light.png), [dark](screenshots/logs-dark.png). Row by row:
following / paused with search, long lines / service filter, follow ended /
failed, native / stopped.
The paused-search fixture shows its active query in the search field. Finite
reads for observed stopped projects include that state alongside the stream status.
The paused fixture also demonstrates the overflow count. Pause has no timeout;
following resumes through Resume, not automatically when scrolling to the bottom.

## Not yet

The Activity tab, CPU and memory, onboarding, always-on, daemon actions and
upgrades come in later units. The design and the CLI/daemon requests they
need are in `DESIGN.md`.

## Env tab (names only)

Expand Down
Loading
Loading