How to Get Diagnostic Information About Active Terminal Command Processes in Freebuff
Freebuff exposes active terminal command diagnostics through the CLI's collectProcessDiagnostics() function and the SDK's runTerminalCommand tool, capturing PID, command arguments, timestamps, and recent output without requiring additional permissions.
The CodebuffAI/freebuff repository ships with built-in observability for every subprocess it manages. When you spawn a terminal command through Freebuff—whether via the interactive TUI or the TypeScript SDK—the runtime maintains a read-only terminal watchdog record. This record contains everything needed to debug hanging processes or audit resource usage, and you can retrieve diagnostic information about active terminal command processes in Freebuff using either the interactive CLI or the programmatic SDK.
CLI Diagnostics Architecture
Freebuff’s command-line interface provides two primary interfaces for inspecting active processes: an interactive slash command for the TUI and a standalone terminal command for shell scripts.
The Terminal Watchdog
At the core of Freebuff’s process monitoring is the terminal watchdog implemented in [cli/src/utils/terminal-watchdog.ts](https://github.com/CodebuffAI/freebuff/blob/main/cli/src/utils/terminal-watchdog.ts). This lightweight module maintains an in-memory registry of every child process spawned by the application.
For each active command, the watchdog stores:
- PID of the child process
- Command-line arguments (excluding sensitive environment variables)
- Start timestamp, last output timestamp, and termination time
- A truncated snippet of the most recent stdout/stderr output
The watchdog exposes a dumpDiagnostics() method that returns a serializable snapshot of this state, ensuring that diagnostic collection is both fast and non-blocking.
The /diagnostics Slash Command
When running Freebuff’s interactive TUI, you can invoke the diagnostics collector instantly by typing:
/diagnostics
This slash command is registered in [cli/src/data/slash-commands.ts](https://github.com/CodebuffAI/freebuff/blob/main/cli/src/data/slash-commands.ts) and invokes formatProcessDiagnostics(collectProcessDiagnostics()). The resulting markdown table is injected directly into the chat history, giving the LLM immediate context about background tasks.
The diagnostics CLI Command
For non-interactive usage, Freebuff provides a top-level command:
freebuff diagnostics
This command is handled by [cli/src/commands/process-diagnostics.ts](https://github.com/CodebuffAI/freebuff/blob/main/cli/src/commands/process-diagnostics.ts). The implementation calls collectProcessDiagnostics() to gather data from the watchdog, then pipes it through formatProcessDiagnostics() to produce a markdown table suitable for terminal display or log aggregation.
SDK Diagnostics
When integrating Freebuff into your own tools, you can retrieve the same diagnostic payloads programmatically.
Accessing Diagnostics via runTerminalCommand
The primary SDK entry point for subprocess management is [sdk/src/tools/run-terminal-command.ts](https://github.com/CodebuffAI/freebuff/blob/main/sdk/src/tools/run-terminal-command.ts). When you await runTerminalCommand(), the resolved TerminalCommandResult object includes a diagnostics field populated with the same snapshot used by the CLI watchdog:
import { runTerminalCommand } from '@codebuff/sdk';
async function runServer() {
const result = await runTerminalCommand({
command: 'npm',
args: ['run', 'dev'],
cwd: './my-project'
});
// Access diagnostics immediately after completion
console.log('Process ID:', result.diagnostics.pid);
console.log('Start time:', new Date(result.diagnostics.startTime));
console.log('Final output snippet:', result.diagnostics.lastOutput);
}
Polling Active Process Diagnostics
For long-running commands, you may need to inspect the process before it exits. The SDK exposes getRunningCommandDiagnostics(), which queries the watchdog for the current state of an active command without blocking on completion:
import { getRunningCommandDiagnostics } from '@codebuff/sdk';
// Poll every 5 seconds while the process runs
const interval = setInterval(() => {
const snapshot = getRunningCommandDiagnostics();
if (snapshot.status === 'running') {
console.log(`PID ${snapshot.pid} still active, last output: ${snapshot.lastOutput}`);
} else {
clearInterval(interval);
}
}, 5000);
Practical Implementation Examples
Example 1: Inspecting Processes in the TUI
Launch the Freebuff interactive interface and type:
/diagnostics
The terminal renders a markdown table similar to:
### Freebuff process diagnostics
| PID | Command | Started | Last Output | Status |
|-----|---------------|--------------------|--------------------|---------|
| 8421| npm run dev | 2024-09-01 14:32:10| 2024-09-01 14:35:02| running |
| 8507| bun test | 2024-09-01 14:33:45| 2024-09-01 14:34:12| exited |
This output is generated by the formatProcessDiagnostics() helper in [cli/src/commands/process-diagnostics.ts](https://github.com/CodebuffAI/freebuff/blob/main/cli/src/commands/process-diagnostics.ts).
Example 2: Filtering Diagnostics from the Command Line
Pipe the diagnostics output to standard Unix tools to locate specific processes:
freebuff diagnostics | grep "npm run dev"
Because freebuff diagnostics writes markdown to stdout, you can integrate it with awk, jq (via conversion), or CI log parsing systems.
Example 3: Programmatic Collection with the CLI Package
If you are building a custom wrapper around Freebuff, import the collector directly:
import { collectProcessDiagnostics, formatProcessDiagnostics } from '@codebuff/cli';
// Get raw snapshots
const snapshots = collectProcessDiagnostics();
// Format for reporting
const report = formatProcessDiagnostics(snapshots);
console.log(report);
This approach leverages the same functions used internally by the TUI and the standalone CLI, ensuring consistency across interfaces.
Summary
- Freebuff tracks every terminal command via a lightweight watchdog in
cli/src/utils/terminal-watchdog.tsthat records PID, timestamps, and output snippets. - Interactive users can type
/diagnosticsin the TUI to instantly view a formatted table of active processes. - Shell users can run
freebuff diagnosticsto retrieve the same data as markdown for piping or logging. - SDK consumers receive diagnostic metadata automatically in the
TerminalCommandResult.diagnosticsfield, with optional polling viagetRunningCommandDiagnostics(). - All diagnostic access is read-only and requires no additional permissions, environment variables, or external dependencies.
Frequently Asked Questions
What information is included in Freebuff process diagnostics?
Freebuff captures the PID, command-line arguments (excluding environment variables), start time, last output timestamp, exit status (if finished), and a recent snippet of stdout/stderr. This data is stored in-memory by the terminal watchdog and never includes sensitive environment secrets.
How do I check if a terminal command is still running in Freebuff?
Use the SDK's getRunningCommandDiagnostics() method to poll the current status field. Alternatively, run freebuff diagnostics from the CLI and inspect the "Status" column. A value of running indicates the child process has not yet exited.
Can I access diagnostics without using the TUI?
Yes. The freebuff diagnostics command is available as a standalone CLI operation defined in cli/src/commands/process-diagnostics.ts. It outputs markdown to stdout, making it suitable for shell scripts, CI pipelines, and log aggregation without launching the interactive interface.
Where does Freebuff store active process diagnostic data?
Diagnostic data is held in a runtime in-memory registry managed by cli/src/utils/terminal-watchdog.ts. It is not persisted to disk, ensuring that sensitive output snippets remain transient and are automatically cleared when the Freebuff process terminates.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →