# Gadget Drone Sub-Processes The Gadget Code agent manages child processes through gadget-drone's SubProcess system. In the Gadget ecosystem, we refer to a managed child process spawned by gadget-drone as a _SubProcess_. ## Phase Status - **Phase 1 (Complete):** SubProcessService + SubprocessTool internal to drone. - **Phase 2 (Planned):** Expose SubProcess status and logs to gadget-code:frontend (IDE) via gadget-code:backend. ## SubProcessService [Source](../src/services/subprocess.ts) `SubProcessService` is a singleton service that manages child processes on behalf of Gadget Drone. It is started and stopped as part of the standard service lifecycle in `gadget-drone.ts`. On stop, all managed subprocesses are killed (SIGINT with graceful timeout, falling back to SIGKILL) and their log files are removed. ### API | Method | Signature | Description | |---|---|---| | `create` | `(project: IProject, cmd: string, args?: string[]) => Promise` | Spawns a child process, starts writing stdout/stderr to log files under `/subprocess-logs/`. | | `ps` | `() => SubProcess[]` | Returns an array of all managed subprocesses. | | `summarize` | `(sp: SubProcess) => SubProcessSummary` | Returns a serializable summary (without ChildProcess/WriteStream refs). | | `killPid` | `(pid: number) => Promise` | Kills a specific subprocess by PID and removes its log files. | | `killProject` | `(projectId: GadgetId) => Promise` | Kills all subprocesses for a given project. | | `killSubProcess` | `(sp: SubProcess) => Promise` | Kills a subprocess and removes its log files. | | `killAll` | `() => Promise` | Kills all managed subprocesses and removes all log files. | | `haltPid` | `(pid: number) => Promise` | Stops a subprocess by PID but **retains its log files** for inspection. | | `haltSubProcess` | `(sp: SubProcess) => Promise` | Stops a subprocess but retains its log files. | | `getLog` | `(pid: number, stream: "stdout" \| "stderr") => Promise` | Reads the full content of a subprocess's stdout or stderr log file. | ### Lifecycle The service is registered in `GadgetDrone.startServices()` / `stopServices()`. During `stop()`, `killAll()` is called, ensuring no orphaned processes remain when the drone shuts down. ### Process Termination Termination follows a graceful escalation: 1. Send `SIGINT` to the process. 2. Wait up to 5 seconds for the process to exit. 3. If still alive, send `SIGKILL`. 4. Wait up to another 5 seconds. 5. Remove stdout/stderr listeners. 6. Close log file streams. For `kill`, log files are deleted after termination. For `halt`, log files are preserved. ## SubprocessTool [Source](../src/tools/system/subprocess.ts) The `subprocess` tool is registered in the agent's toolbox for modes: `Build`, `Test`, `Ship`, `Develop`. It provides a single function with a `cmd` parameter that dispatches to the appropriate operation. ### Tool Definition **Name:** `subprocess` **Category:** `system` **Parameters:** | Parameter | Type | Required | Description | |---|---|---|---| | `cmd` | string (enum) | yes | One of: `create`, `list`, `kill`, `killAll`, `halt`, `log` | | `command` | string | for `create` | The executable to spawn (e.g., `node`, `npm`, `python`) | | `args` | string[] | for `create` | Command-line arguments for the spawned process | | `pid` | number | for `kill`, `halt`, `log` | The managed process ID | | `which` | string (enum) | for `log` | `"stdout"` or `"stderr"` | ### Commands #### `create` Spawns a new child process in the project directory. Logs stdout and stderr to `/subprocess-logs/`. Response: ``` SUBPROCESS CREATED pid: 12345 stdout: /path/to/.gadget/subprocess-logs/subproc-12345.stdout.log stderr: /path/to/.gadget/subprocess-logs/subproc-12345.stderr.log ``` #### `list` Returns all currently managed subprocesses with their PIDs, project slugs, and timestamps. Response: ``` SUBPROCESS LIST pid: 12345 | project: my-project | created: ... | updated: ... ``` #### `kill` Terminates a subprocess and removes its log files. Uses SIGINT with graceful escalation. Response: ``` SUBPROCESS KILLED pid: 12345 ``` #### `killAll` Terminates all managed subprocesses and removes all log files. Response: ``` SUBPROCESS KILLALL All managed subprocesses have been terminated and their logs removed. ``` #### `halt` Terminates a subprocess but retains its log files. Useful for inspecting logs after process exit. Response: ``` SUBPROCESS HALTED pid: 12345 The process has been stopped. Log files are retained for inspection. ``` #### `log` Reads stdout or stderr output from a subprocess's log file. Response: ``` SUBPROCESS LOG (stdout) pid: 12345 --- ``` ## Integration Points ### System Prompts All agent modes include a **Process Management** block in their system prompt. The block is loaded from [process-management-block.md](../../gadget-code/data/prompts/common/process-management-block.md) and rendered via `{{process_management_block}}` in the mode templates. This tells the agent about the `subprocess` tool and how to use it. ### Shutdown `gadget-drone.ts` calls `SubProcessService.stop()` during shutdown, which triggers `killAll()` to clean up any remaining child processes. ## Tests | File | What it covers | |---|---| | `src/services/subprocess.test.ts` | SubProcessService: create, ps, killPid, killAll, haltPid, getLog, error cases | | `src/tools/system/subprocess.test.ts` | SubprocessTool: all 6 commands, parameter validation, service error handling |