runAgentCommand method
Runs line in this (the user's current) interactive session and returns
its captured output and exit code — used by the AI agent so its commands
run in the real terminal shell (with a PTY, shared cwd/env and sudo
credentials), streaming live and letting the user answer prompts.
Rejects if the session has ended or a command is already in flight. The command's output still streams to onOutput/onStderr (the user sees it) while it is also captured for the caller.
Implementation
Future<ShellRunResult> runAgentCommand(String line) {
if (_ended) {
return Future.error(StateError('session has ended'));
}
if (_inFlight || _agentRun != null) {
return Future.error(StateError('a command is already running'));
}
if (line.trim().isEmpty) {
return Future.value(const ShellRunResult(<int>[], 0));
}
final completer = Completer<ShellRunResult>();
_agentRun = completer;
_agentCapture = BytesBuilder(copy: false);
_inFlight = true;
onPassthrough(true);
final command = _dialect.wrapCommand(
line,
interactive: _interactive,
tail: _dialect.agentMarker(_marker),
);
_send('$command\n');
return completer.future;
}