summaryrefslogtreecommitdiff
path: root/internal/cli
diff options
context:
space:
mode:
Diffstat (limited to 'internal/cli')
-rw-r--r--internal/cli/command.go1
-rw-r--r--internal/cli/command_test.go12
-rw-r--r--internal/cli/flags.go2
-rw-r--r--internal/cli/flags_test.go3
4 files changed, 17 insertions, 1 deletions
diff --git a/internal/cli/command.go b/internal/cli/command.go
index 43a03bc..526dffe 100644
--- a/internal/cli/command.go
+++ b/internal/cli/command.go
@@ -22,6 +22,7 @@ Examples:
totalrecall # Launch interactive GUI (default)
totalrecall ябълка # Generate materials for "apple" via CLI
totalrecall --batch words.txt # Process multiple words from file
+ totalrecall --retry-failed-assets # Resume incomplete cards in the output directory
totalrecall --archive # Archive existing cards directory
Batch file formats:
diff --git a/internal/cli/command_test.go b/internal/cli/command_test.go
index 80626eb..4c95c3b 100644
--- a/internal/cli/command_test.go
+++ b/internal/cli/command_test.go
@@ -32,6 +32,9 @@ func TestCreateRootCommand(t *testing.T) {
if !strings.Contains(cmd.Long, "Explicit CLI and batch runs also use Nano Banana by default") {
t.Errorf("Expected Long description to describe the CLI and batch Nano Banana default")
}
+ if !strings.Contains(cmd.Long, "--retry-failed-assets") {
+ t.Errorf("Expected Long description to mention retry-failed-assets mode")
+ }
// Test that flags are set up
flagTests := []struct {
@@ -45,6 +48,7 @@ func TestCreateRootCommand(t *testing.T) {
{"batch", true},
{"skip-audio", true},
{"skip-images", true},
+ {"retry-failed-assets", true},
{"anki", true},
{"anki-csv", true},
{"deck-name", true},
@@ -119,6 +123,14 @@ func TestSetupFlags(t *testing.T) {
t.Errorf("Expected image-api help to describe the CLI Nano Banana default and config fallback, got %q", imageAPIFlag.Usage)
}
+ retryFailedAssetsFlag := cmd.Flags().Lookup("retry-failed-assets")
+ if retryFailedAssetsFlag == nil {
+ t.Fatal("retry-failed-assets flag not found")
+ }
+ if !strings.Contains(retryFailedAssetsFlag.Usage, "stopping on the first error") {
+ t.Errorf("Expected retry-failed-assets help to describe stop-on-first-error behavior, got %q", retryFailedAssetsFlag.Usage)
+ }
+
openAIVoiceFlag := cmd.Flags().Lookup("openai-voice")
if openAIVoiceFlag == nil {
t.Fatal("openai-voice flag not found")
diff --git a/internal/cli/flags.go b/internal/cli/flags.go
index 43e3b23..bdcc88b 100644
--- a/internal/cli/flags.go
+++ b/internal/cli/flags.go
@@ -38,6 +38,7 @@ type Flags struct {
VideoEnabled bool // --video: whether to prompt for Veo video generation after --story completes
SkipAudio bool
SkipImages bool
+ RetryFailedAssets bool
GenerateAnki bool
AnkiCSV bool
DeckName string
@@ -131,6 +132,7 @@ func setupFlags(cmd *cobra.Command, flags *Flags) {
"Prompt to generate Veo videos after comic generation (default true; use --video=false to skip)")
cmd.Flags().BoolVar(&flags.SkipAudio, "skip-audio", false, "Skip audio generation")
cmd.Flags().BoolVar(&flags.SkipImages, "skip-images", false, "Skip image download")
+ cmd.Flags().BoolVar(&flags.RetryFailedAssets, "retry-failed-assets", false, "Scan existing cards and regenerate missing or failed audio/image assets, stopping on the first error")
cmd.Flags().BoolVar(&flags.GenerateAnki, "anki", false, "Generate Anki import file (APKG format by default, use --anki-csv for legacy CSV)")
cmd.Flags().BoolVar(&flags.AnkiCSV, "anki-csv", false, "Generate legacy CSV format instead of APKG when using --anki")
cmd.Flags().StringVar(&flags.DeckName, "deck-name", flags.DeckName, "Deck name for APKG export")
diff --git a/internal/cli/flags_test.go b/internal/cli/flags_test.go
index 4b59bee..5c56770 100644
--- a/internal/cli/flags_test.go
+++ b/internal/cli/flags_test.go
@@ -51,6 +51,7 @@ func TestNewFlags(t *testing.T) {
}{
{"SkipAudio", flags.SkipAudio},
{"SkipImages", flags.SkipImages},
+ {"RetryFailedAssets", flags.RetryFailedAssets},
{"GenerateAnki", flags.GenerateAnki},
{"AnkiCSV", flags.AnkiCSV},
{"ListModels", flags.ListModels},
@@ -94,7 +95,7 @@ func TestFlagsStructure(t *testing.T) {
expectedFields := []string{
"CfgFile", "OutputDir", "AudioFormat", "AudioFormatSpecified", "AudioProvider", "ImageAPI", "ImageAPISpecified", "BatchFile",
- "SkipAudio", "SkipImages", "GenerateAnki", "AnkiCSV", "DeckName",
+ "SkipAudio", "SkipImages", "RetryFailedAssets", "GenerateAnki", "AnkiCSV", "DeckName",
"ListModels", "AllVoices", "NoAutoPlay",
"OpenAIModel", "OpenAIVoice", "OpenAISpeed", "OpenAIInstruction",
"OpenAIImageModel", "OpenAIImageSize", "OpenAIImageQuality", "OpenAIImageStyle",