Problem Description / Motivation
The current Terminal UI in client/src/ui/terminal_ui.cpp renders processes strictly as a flat list sorted by CPU, memory, PID, or thread count. While this works well for identifying individual resource-heavy tasks, it makes it difficult to diagnose multi-process application workloads (e.g. systemd service trees, container process trees, fork-exec workers like nginx/gunicorn/postgres, or parallel build jobs). Operators need the ability to view parent-child hierarchies (pstree-style) with interactive fold/unfold capability to quickly isolate rogue process subtrees and inspect aggregated resource usage.
Technical Details & Affected Components
- Procfs Parsing & Data Models:
- In
server/src/collectors/linux_samples.cpp (ParseProcess), /proc/[pid]/stat is parsed, but the parent process ID (ppid, field 4 in stat) is currently omitted.
- In
common/include/common/models/process_metrics.hpp and common/src/common/models/process_metrics.cpp, ProcessInfo lacks a ppid field.
- In
common/src/protocol.cpp, Decode() validates JSON process records without ppid. Adding ppid should be backward compatible or versioned cleanly.
- Client Terminal UI & State:
- In
client/include/client/ui/terminal_ui.hpp and client/src/ui/terminal_ui.cpp:
ViewState only tracks sort and flat scroll.
Processes() sorts the flat vector and prints rows directly.
- In
client/src/app/client_app.cpp:
- Key dispatch handles
j, k, c, m, p, t, but lacks a keybinding to toggle tree view (e.g., F5 or T) or toggle folding on a selected node (e.g., Space or Enter, + / -).
Proposed Implementation Strategy
- Model & Serialization:
- Parse field 4 (
ppid) in server/src/collectors/linux_samples.cpp during /proc/[pid]/stat parsing into ProcessSample.
- Add
ProcessID ppid{} to ProcessInfo, and serialize it to/from JSON in ProcessInfo::ToJson() and ProcessInfo::FromJson().
- Update protocol validator in
common/src/protocol.cpp to accept optional/required ppid.
- Process Tree Data Structure:
- Construct a directed tree/forest (
std::unordered_map<ProcessID, std::vector<ProcessID>>) rooted at PID 1 (or orphaned/root parents) in client/src/ui/terminal_ui.cpp when in tree mode.
- Support collapsible branches via a set of collapsed PIDs:
std::unordered_set<ProcessID> collapsed_nodes.
- Implement depth-first traversal generating tree branch drawing glyphs (e.g.,
├─, └─, │ , [+], [-]).
- Interactive Navigation:
- Add cursor selection tracking in
ViewState (selected PID row) in client_app.cpp.
- Support toggling tree mode with
T or F5.
- Support expanding/collapsing nodes with
Space, +, -, or arrow keys (Left collapses, Right expands).
- Show cumulative subtree metrics (summed RSS and CPU%) on collapsed parent nodes.
Acceptance Criteria
Problem Description / Motivation
The current Terminal UI in
client/src/ui/terminal_ui.cpprenders processes strictly as a flat list sorted by CPU, memory, PID, or thread count. While this works well for identifying individual resource-heavy tasks, it makes it difficult to diagnose multi-process application workloads (e.g. systemd service trees, container process trees, fork-exec workers like nginx/gunicorn/postgres, or parallel build jobs). Operators need the ability to view parent-child hierarchies (pstree-style) with interactive fold/unfold capability to quickly isolate rogue process subtrees and inspect aggregated resource usage.Technical Details & Affected Components
server/src/collectors/linux_samples.cpp(ParseProcess),/proc/[pid]/statis parsed, but the parent process ID (ppid, field 4 instat) is currently omitted.common/include/common/models/process_metrics.hppandcommon/src/common/models/process_metrics.cpp,ProcessInfolacks appidfield.common/src/protocol.cpp,Decode()validates JSON process records withoutppid. Addingppidshould be backward compatible or versioned cleanly.client/include/client/ui/terminal_ui.hppandclient/src/ui/terminal_ui.cpp:ViewStateonly trackssortand flatscroll.Processes()sorts the flat vector and prints rows directly.client/src/app/client_app.cpp:j,k,c,m,p,t, but lacks a keybinding to toggle tree view (e.g.,F5orT) or toggle folding on a selected node (e.g.,SpaceorEnter,+/-).Proposed Implementation Strategy
ppid) inserver/src/collectors/linux_samples.cppduring/proc/[pid]/statparsing intoProcessSample.ProcessID ppid{}toProcessInfo, and serialize it to/from JSON inProcessInfo::ToJson()andProcessInfo::FromJson().common/src/protocol.cppto accept optional/requiredppid.std::unordered_map<ProcessID, std::vector<ProcessID>>) rooted at PID 1 (or orphaned/root parents) inclient/src/ui/terminal_ui.cppwhen in tree mode.std::unordered_set<ProcessID> collapsed_nodes.├─,└─,│,[+],[-]).ViewState(selected PID row) inclient_app.cpp.TorF5.Space,+,-, or arrow keys (Leftcollapses,Rightexpands).Acceptance Criteria
ppidis reliably collected on Linux and transmitted via snapshot protocol without breaking backwards compatibility.T).