execute method
Execute the command.
Implementation
@override
Future<CommandResult> execute(String args, ToolUseContext context) async {
final customTitle = args.trim().isEmpty ? null : args.trim();
final originalSessionId = getSessionId();
try {
final cwd = getCwd();
final projectDir = getProjectDir(cwd);
final result = await createFork(
currentTranscriptPath: getTranscriptPath(),
originalSessionId: originalSessionId,
projectDir: projectDir,
customTitle: customTitle,
);
// Derive first prompt for title fallback.
final firstUser = result.serializedMessages
.where((m) => m.type == 'user')
.firstOrNull;
final firstPrompt = deriveFirstPrompt(firstUser);
// Save custom title — use provided title or firstPrompt as default.
// This ensures /status and /resume show the same session name.
// Always add " (Branch)" suffix to make it clear this is a branched
// session. Handle collisions by adding a number suffix.
final baseName = result.title ?? firstPrompt;
final effectiveTitle = await getUniqueForkName(projectDir, baseName);
await saveCustomTitle(
projectDir,
result.sessionId,
effectiveTitle,
result.forkPath,
);
// Resume into the fork if callback is available.
final titleInfo = result.title != null ? ' "${result.title}"' : '';
final resumeHint =
'\nTo resume the original: neomage -r $originalSessionId';
final successMessage =
'Branched conversation$titleInfo. '
'You are now in the branch.$resumeHint';
if (onResume != null) {
await onResume!(result.sessionId, result.forkPath, 'fork');
return TextCommandResult(successMessage);
} else {
// Fallback if resume not available.
return TextCommandResult(
'Branched conversation$titleInfo. '
'Resume with: /resume ${result.sessionId}',
);
}
} catch (e) {
final message = e is StateError ? e.message : 'Unknown error occurred';
return TextCommandResult('Failed to branch conversation: $message');
}
}