gadget/gadget-drone/docs/subprocess.md
Rob Colbert d04453016d Phase 1: SubProcess service and agent tool
Complete Phase 1 of subprocess management in gadget-drone:
- SubProcessService with graceful shutdown (SIGINT→SIGKILL), halt, getLog
- SubprocessTool with create/list/kill/killAll/halt/log commands
- Registered in agent toolbox for build/test/ship/develop modes
- Fixed missing {{process_management_block}} replacement in chat-session.ts
- 34 unit tests across service and tool
- Comprehensive documentation in docs/subprocess.md
2026-05-14 12:59:05 -04:00

5.4 KiB

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

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<SubProcess> Spawns a child process, starts writing stdout/stderr to log files under <gadgetDir>/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<boolean> Kills a specific subprocess by PID and removes its log files.
killProject (projectId: GadgetId) => Promise<void> Kills all subprocesses for a given project.
killSubProcess (sp: SubProcess) => Promise<boolean> Kills a subprocess and removes its log files.
killAll () => Promise<boolean> Kills all managed subprocesses and removes all log files.
haltPid (pid: number) => Promise<boolean> Stops a subprocess by PID but retains its log files for inspection.
haltSubProcess (sp: SubProcess) => Promise<boolean> Stops a subprocess but retains its log files.
getLog (pid: number, stream: "stdout" | "stderr") => Promise<string> 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

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 <gadgetDir>/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
---
<log content>

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 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