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 detectedisFinished— true when completion markers are foundisRunning— 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
src/tools/improved-process-tools.ts— ImplementsstartProcess, orchestrates subprocess launch, and consumesanalyzeProcessStateresultssrc/utils/process-detection.ts— ContainsanalyzeProcessState, theREPL_PROMPTSdictionary, andformatProcessStateMessagesrc/terminal-manager.ts— Manages actual process spawning, output buffering, and PID trackingsrc/tools/schemas.ts— Defines Zod schemas forstart_processinput validation
Summary
- Regex-based prompt matching in
analyzeProcessStateenables instantaneous detection without polling - The
REPL_PROMPTSdictionary 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
ProcessStateobject 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →