run method
Runs bd <args>. Throws BdTimeoutException if the call exceeds
timeout (the implementation kills the process tree); never throws for a
non-zero exit — that is reported via BdResult.exitCode for the caller to
route through BdCommandFailed.fromOutput.
stdin, when provided, is written to the child's stdin and the stream is
closed (EOF). bd batch reads its line-oriented script this way — one
spawn, one Dolt transaction (ADR-0001 D4).
Implementation
@override
Future<BdResult> run(List<String> args, {Duration? timeout, String? stdin}) {
calls.add(List<String>.unmodifiable(args));
stdins.add(stdin);
final sub = args.isNotEmpty ? args.first : '';
if (sub == 'export') {
// Legacy tripwire payload retained for tests that deliberately exercise
// an unsupported command; production readers never reach this branch.
final depsByIssue = <String, List<Map<String, dynamic>>>{};
for (final dep in exportDependencies) {
(depsByIssue[dep.issueId] ??= <Map<String, dynamic>>[]).add(
dep.toJson(),
);
}
final jsonl = exportBeads
.map((b) {
final json = b.toJson();
final deps = depsByIssue[b.id];
if (deps != null) json['dependencies'] = deps;
return jsonEncode(json);
})
.join('\n');
return Future<BdResult>.value(
BdResult(exitCode: 0, stdout: jsonl, stderr: ''),
);
}
if (sub == 'create' && args.length > 1 && args[1] == '--graph') {
// `bd create --graph <plan-file> [--ephemeral] --json` — a graph-apply
// pour reports a `key → id` MAP (`data.ids`), never a single `data.id`.
return Future<BdResult>.value(
BdResult(
exitCode: 0,
stdout: jsonEncode({
'schema_version': 1,
'data': {'ids': graphApplyIds},
}),
stderr: '',
),
);
}
final data = switch (sub) {
'create' => '{"id":"$_createdId"}',
_ => '{"id":"${args.length >= 2 ? args[1] : ''}"}',
};
return Future<BdResult>.value(
BdResult(
exitCode: 0,
stdout: '{"schema_version":1,"data":$data}',
stderr: '',
),
);
}