How the `start_process` Tool Detects Interactive Input Readiness in DesktopCommanderMCP

The start_process tool detects when a program is ready for interactive input by capturing initial output and matching it against a dictionary of known REPL prompts using regex pattern matching in analyzeProcessState.

The start_process tool in the DesktopCommanderMCP repository (wonderwhy-er/DesktopCommanderMCP) enables AI agents to launch subprocesses and immediately determine whether the spawned program is awaiting user interaction. This capability is critical for interactive workflows like Python REPLs, Node.js shells, or custom CLI tools that pause for input.

The Detection Pipeline in start_process

The interactive input detection follows a four-stage pipeline orchestrated across three core files.

Stage 1: Process Launch via TerminalManager

When start_process is invoked, it delegates execution to the TerminalManager. The startProcess function in src/tools/improved-process-tools.ts calls terminalManager.executeCommand to spawn the subprocess and buffer its initial output.

Stage 2: State Analysis with analyzeProcessState

The raw output is passed to analyzeProcessState from src/utils/process-detection.ts. This utility function performs the actual detection logic:

// improved-process-tools.ts – lines 185-186
const processState = analyzeProcessState(result.output, result.pid);

The analyzeProcessState implementation scans the output's last line against a curated dictionary of REPL prompts:

// process-detection.ts
const allPrompts = Object.values(REPL_PROMPTS).flat();
const detectedPrompt = allPrompts.find(prompt =>
  lastLine.endsWith(prompt) || lastLine.includes(prompt)
);

if (detectedPrompt) {
  return {
    isWaitingForInput: true,
    isFinished: false,
    isRunning: true,
    detectedPrompt,
    lastOutput: output
  };
}

Stage 3: Return of ProcessState Object

The function returns a ProcessState object containing boolean flags that classify the process condition:

  • isWaitingForInput — true when a REPL prompt is detected
  • isFinished — true when completion markers are found
  • isRunning — true for active processes

Stage 4: User Feedback Generation

If isWaitingForInput evaluates to true, start_process appends a status message using formatProcessStateMessage:

// improved-process-tools.ts
let statusMessage = '';
if (processState.isWaitingForInput) {
  statusMessage = `\n🔄 ${formatProcessStateMessage(processState, result.pid)}`;
}

The REPL_PROMPTS Dictionary

The detection accuracy depends on the REPL_PROMPTS map maintained in src/utils/process-detection.ts. This dictionary covers common interactive environments:

Language/Shell Detected Prompts
Python >>> , ...
Node.js >
R > , +
Julia julia> , help?>
Bash/Zsh/Sh $ , # , %

Additional patterns detect completion indicators and error states to distinguish finished processes from interactive ones.

Practical Usage Examples

Starting a Python REPL with automatic readiness detection:

// Example: Starting a Python REPL
await startProcess({ command: "python", timeout_ms: 30000 });
// → Output includes: "🔄 Process 1234 is waiting for input (detected: ">>>")"

Launching a Node.js script that may pause for interaction:

// Example: Starting a script with potential interactive pause
await startProcess({ command: "node myScript.js" });
// If the script ends with "> ", the response shows waiting-for-input status

Key Implementation Files

Summary

  • Regex-based prompt matching in analyzeProcessState enables instantaneous detection without polling
  • The REPL_PROMPTS dictionary supports Python, Node, R, Julia, and common shells out of the box
  • Detection operates on the first output chunk, making it suitable for fast feedback loops
  • The ProcessState object provides structured classification: waiting, finished, or running
  • Status messages are user-friendly via formatProcessStateMessage

Frequently Asked Questions

How does start_process handle programs without standard REPL prompts?

The tool relies on the REPL_PROMPTS dictionary for automatic detection. Custom prompts can be added to this map in src/utils/process-detection.ts. Programs that emit no recognizable pattern will report isWaitingForInput: false, and the caller must use timeout_ms or manual polling via subsequent status checks.

Can the detection work for GUI applications or silent daemons?

No. The analyzeProcessState function examines stdout/stderr text output only. GUI applications without console output or daemons that detach from standard streams cannot be assessed for interactive readiness through this mechanism.

What happens if a program outputs a prompt string mid-execution?

The detection logic specifically checks the last line of output. Mid-stream prompt strings do not trigger isWaitingForInput unless they appear at the buffer's terminus when analyzeProcessState is invoked.

Is the prompt detection case-sensitive?

Yes. The REPL_PROMPTS dictionary uses literal string matching with endsWith() and includes(). Prompt variants requiring case-insensitive matching would need custom entries in the dictionary.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →