execute method
Execute and return result via callback.
Implementation
@override
Future<CommandResult> execute(String args, ToolUseContext context) async {
// Check if skill directory exists.
final dir = await getThinkbackSkillDir();
if (dir == null) {
return const TextCommandResult(
'Thinkback plugin not found. Install it via /plugin command.\n'
'Try running /plugin to manually install the think-back plugin.',
);
}
// Check if animation has been generated.
final dataPath = p.join(dir, 'year_in_review.js');
final hasAnimation = await _pathExists(dataPath);
if (hasAnimation) {
// If animation exists, present menu options.
final menuText = StringBuffer()
..writeln('Think Back on 2025 with Neomage')
..writeln()
..writeln('Options:')
..writeln(' 1. Play animation — Watch your year in review')
..writeln(' 2. Edit content — Modify the animation')
..writeln(' 3. Fix errors — Fix validation or rendering issues')
..writeln(' 4. Regenerate — Create a new animation from scratch')
..writeln()
..writeln('Use /think-back play to play the animation, or')
..writeln('/think-back regenerate to create a new one.');
// Handle sub-commands.
final subCommand = args.trim().toLowerCase();
if (subCommand == 'play') {
final result = await playAnimation(dir);
return TextCommandResult(result.message);
} else if (subCommand == 'edit') {
return const TextCommandResult(_editPrompt);
} else if (subCommand == 'fix') {
return const TextCommandResult(_fixPrompt);
} else if (subCommand == 'regenerate') {
return const TextCommandResult(_regeneratePrompt);
}
return TextCommandResult(menuText.toString());
}
// No animation yet — offer to generate.
if (args.trim().toLowerCase() == 'regenerate' || args.trim().isEmpty) {
return const TextCommandResult(_regeneratePrompt);
}
return const TextCommandResult(
'No animation found. Run /think-back to generate your '
'personalized year-in-review animation.',
);
}