You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Now that issue #44 has implemented the pluggable storage provider infrastructure, we need user-facing commands to manage storage providers. This feature will allow users to switch providers, migrate data between providers, validate configurations, and potentially route different note types to different providers.
✅ Two provider implementations: DefaultStorageProvider, ObsidianStorageProvider
✅ Setup wizard integration for initial provider selection
✅ Options pattern configuration (StorageOptions)
✅ Backward compatibility with legacy MemoryDirectory
What's Missing: User-facing commands to manage storage post-setup
Architectural Clarity:
Storage provider infrastructure lives in src/Infrastructure/Storage/ (cross-cutting)
Storage management feature should live in src/Features/StorageManagement/ (user commands)
This properly applies VSA: features consume infrastructure, infrastructure doesn't execute user commands
Proposed Commands
1. tom storage list
Purpose: List available storage providers with metadata
Output:
Available Storage Providers:
* default (active)
Default File System
TST-native hierarchical structure optimized for organization.
Current location: /Users/john/ten-second-tom
obsidian
Obsidian Vault Integration
Store entries in an Obsidian vault for seamless integration.
Implementation Notes:
Use IStorageProviderFactory.GetAvailableProviders() (may need to add this method)
Show current active provider from IOptions<StorageOptions>
✗ Storage Provider: Obsidian Vault Integration
✗ Vault Path: /Users/john/Documents/MyVault
Error: .obsidian directory not found
Suggestion: Ensure the vault has been opened in Obsidian at least once
IPathTransformationService - Path/name transformations between providers
Key Interfaces
namespaceTenSecondTom.Features.StorageManagement.Services;/// <summary>/// Service for migrating storage entries between providers./// </summary>publicinterfaceIStorageMigrationService{/// <summary>/// Plans a migration from one provider to another./// </summary>Task<MigrationPlan>PlanMigrationAsync(IStorageProvidersourceProvider,IStorageProvidertargetProvider,MigrationOptionsoptions,CancellationTokencancellationToken);/// <summary>/// Executes a migration plan./// </summary>Task<Result<MigrationResult>>ExecuteMigrationAsync(MigrationPlanplan,IProgress<MigrationProgress>?progress,CancellationTokencancellationToken);/// <summary>/// Creates a backup of source entries before migration./// </summary>Task<Result<string>>CreateBackupAsync(IStorageProvidersourceProvider,CancellationTokencancellationToken);}/// <summary>/// Service for transforming file paths and names between provider conventions./// </summary>publicinterfaceIPathTransformationService{/// <summary>/// Transforms a file path from source provider format to target provider format./// </summary>stringTransformPath(stringsourcePath,stringsourceProviderId,stringtargetProviderId);/// <summary>/// Transforms entry metadata between provider conventions./// </summary>EntryMetadataTransformMetadata(EntryMetadatasourceMetadata,stringtargetProviderId);}
Implementation Phases
Phase 1: Core Commands (MVP)
tom storage list - Discover available providers
tom storage validate - Health check current storage
tom storage info - Show current configuration
Effort: 2-3 days Value: Immediate visibility and diagnostics
Phase 2: Provider Switching
tom storage switch - Change provider interactively
Configuration file updates
Provider-specific prompts (reuse Setup wizard UI)
Effort: 2-3 days Value: Enable post-setup provider changes
Phase 3: Data Migration
tom storage migrate - Full migration workflow
IStorageMigrationService implementation
Path transformation logic
Dry-run and validation
Progress reporting
Effort: 4-5 days Value: Seamless data portability
Phase 4: Advanced Features (Future)
tom storage repair - Fix common issues
Multi-provider routing (route different note types to different providers)
Scheduled migrations or sync
Effort: TBD Value: Power user features
Testing Requirements
Following critical path testing approach from #44:
Unit Tests (per use case)
ListProviders.cs Tests:
Handler returns all discovered providers
Active provider is marked correctly
Empty provider list handled gracefully
ValidateStorage.cs Tests:
Validation succeeds for healthy storage
Validation fails for missing directories
Validation fails for permission issues
Clear error messages provided
SwitchProvider.cs Tests:
Switch updates configuration correctly
Invalid provider ID rejected
Configuration validated before committing
Rollback on validation failure
MigrateStorage.cs Tests:
Migration plan calculates correct entry counts
Path transformation works for all providers
Backup created before migration
Failed migration rolls back gracefully
Progress reporting updates correctly
GetStorageInfo.cs Tests:
Info displays all configuration fields
Storage statistics calculated correctly
Health checks detect issues
Integration Tests
StorageManagementWorkflowTests.cs:
Complete switch workflow (Default → Obsidian)
Complete migration workflow with validation
Switch without migrate (manual migration)
Dry-run migration (no side effects)
Backup and restore workflow
CLI Tests
StorageCommandsTests.cs:
All subcommands registered correctly
Options parsed and validated
Exit codes correct (0 success, 1 failure)
Error messages displayed to stderr
Configuration Impact
No changes to StorageOptions - this feature only reads configuration and updates via standard mechanisms.
Configuration Update Strategy:
Use IConfiguration to update ~/.tom/config/tom-config.json
Preserve all non-storage configuration
Validate JSON before writing
Create backup of config before updates
User Experience Considerations
Interactive vs Non-Interactive
Interactive Mode (default):
Prompts for all required values
Provides suggestions and validation feedback
Asks for confirmation on destructive operations
Shows progress indicators for long operations
Non-Interactive Mode (CI/CD, scripting):
All values provided via flags
--force skips confirmation prompts
--dry-run available for preview
Exit codes indicate success/failure
Error Handling
Clear error messages:
✗ Error: Cannot migrate to Obsidian provider
Reason: Target vault is not writable
Path: /Users/john/Documents/MyVault
Suggestions:
• Check file system permissions: ls -la /Users/john/Documents
• Ensure vault is not on a read-only volume
• Grant Full Disk Access on macOS (System Preferences → Security)
For more help: tom storage validate
Graceful degradation:
If provider discovery fails, show last known providers
If validation fails, show cached status
Always provide --help for self-service
Progress Indicators
Use Spectre.Console for rich CLI experience:
Progress bars for migration operations
Status indicators (✓, ✗, ⚠)
Tables for structured output (storage info, provider list)
Confirmation prompts with sensible defaults
Documentation Updates
README.md
Add new section after "Setup":
## Storage Management
After initial setup, you can manage storage providers using the `tom storage` command:
### List Available Providers\`\`\`bash
tom storage list
\`\`\`### Switch Storage Provider\`\`\`bash
# Interactive mode
tom storage switch
# Non-interactive with migration
tom storage switch --provider obsidian --migrate
\`\`\`### Migrate Data Between Providers\`\`\`bash
tom storage migrate --from default --to obsidian
\`\`\`### View Storage Information\`\`\`bash
tom storage info
\`\`\`### Validate Storage Health\`\`\`bash
tom storage validate
\`\`\`
📚 See [Storage Management Guide](docs/STORAGE-MANAGEMENT.md) for detailed documentation.
docs/STORAGE-MANAGEMENT.md (New)
Create comprehensive guide covering:
All command usage with examples
Migration workflows and best practices
Troubleshooting common migration issues
Backup and recovery procedures
Advanced usage (dry-run, filters, scripting)
docs/OBSIDIAN-STORAGE.md
Update "Migrating from Default Storage" section:
## Migrating from Default Storage### Automated Migration (Recommended)
Use the built-in migration command:
\`\`\`bash
# Interactive migration wizard
tom storage migrate
# Or non-interactive
tom storage migrate --from default --to obsidian \
--target /Users/yourname/Documents/MyVault \
--subdirectory ten-second-tom
\`\`\`
This will:
- Automatically transform file paths and names
- Preserve all metadata
- Create a backup before migration
- Validate all migrated entries
### Manual Migration
See [Manual Migration Steps](#manual-migration-steps) if you prefer manual control.
Success Criteria
✅ Commands Implemented:
tom storage list - Shows available providers
tom storage validate - Validates current storage
tom storage info - Shows storage details
tom storage switch - Changes provider
tom storage migrate - Migrates data
✅ Testing:
Unit tests for all use case handlers (80%+ coverage)
Integration tests for complete workflows
CLI tests for command registration and options
✅ Documentation:
README.md updated with storage management section
docs/STORAGE-MANAGEMENT.md created
docs/OBSIDIAN-STORAGE.md updated with automated migration
Provider Discovery Enhancement: Should IStorageProviderFactory expose GetAvailableProviders() or should we add IProviderMetadata?
Configuration Updates: Should we use IConfiguration directly or create a IConfigurationWriter abstraction?
Backup Location: Should backups live in ~/.tom/backups/ or within the storage root?
Migration Atomicity: Should we implement rollback on partial migration failure?
Concurrent Access: Should we implement file locking during migration to prevent concurrent writes?
Multi-Provider Routing: Phase 4 feature - allow different note types to different providers (e.g., daily → Obsidian, weekly → Default). This would require routing configuration and multi-provider resolution.
Feature (this issue): User-facing commands that consume infrastructure
The feature is self-contained in src/Features/StorageManagement/ and has no cross-dependencies on other features. It only depends on shared infrastructure (IStorageProvider, IOptions<StorageOptions>).
Summary
Now that issue #44 has implemented the pluggable storage provider infrastructure, we need user-facing commands to manage storage providers. This feature will allow users to switch providers, migrate data between providers, validate configurations, and potentially route different note types to different providers.
Context
Completed in #44:
IStorageProvider,IStorageProviderFactory, assembly scanningDefaultStorageProvider,ObsidianStorageProviderStorageOptions)MemoryDirectoryWhat's Missing: User-facing commands to manage storage post-setup
Architectural Clarity:
src/Infrastructure/Storage/(cross-cutting)src/Features/StorageManagement/(user commands)Proposed Commands
1.
tom storage listPurpose: List available storage providers with metadata
Output:
Implementation Notes:
IStorageProviderFactory.GetAvailableProviders()(may need to add this method)IOptions<StorageOptions>DisplayName,Description2.
tom storage validatePurpose: Validate current storage configuration and provider health
Output (success):
Output (failure):
Implementation Notes:
IStorageProvider.ValidateConfigurationAsync()3.
tom storage switchPurpose: Switch to a different storage provider
Usage:
Workflow:
~/.tom/config/tom-config.json)tom storage migrate)Options:
--provider <id>: Target provider ID (e.g.,default,obsidian)--root <path>: RootDirectory for new provider--subdirectory <name>: Optional subdirectory within root--migrate: Automatically migrate existing entries to new provider--no-migrate: Switch provider without migrating data (user handles manually)--dry-run: Preview configuration changes without applyingImplementation Notes:
ISetupWizardUImethods from Setup feature for consistency4.
tom storage migratePurpose: Migrate entries from current provider to another provider
Usage:
Workflow:
--force)Options:
--from <provider>: Source provider ID--to <provider>: Target provider ID--source <path>: Source root directory (if different from config)--target <path>: Target root directory--dry-run: Show migration plan without executing--backup: Create backup of source before migration (default: true)--delete-source: Delete source entries after successful migration (default: false)--force: Skip confirmation prompt--filter <pattern>: Migrate only entries matching pattern (e.g.,2025-10-*)Output:
Implementation Notes:
IStorageProviderimplementations for reading/writing~/.tom/backups/migration-{timestamp}/)5.
tom storage infoPurpose: Show detailed information about current storage configuration
Output:
Implementation Notes:
IOptions<StorageOptions>IStorageProviderto scan directories6.
tom storage repair(Future Enhancement)Purpose: Repair common storage issues
Potential Use Cases:
Note: This can be added in a future iteration after core management commands are stable.
Architectural Design
Vertical Slice Structure
CLI Command Structure
Dependencies
Feature consumes Infrastructure:
IStorageProviderFactory- List and create providersIStorageProvider- Validate, read, write entriesIOptions<StorageOptions>- Current configurationIConfiguration- Update configuration fileFeature-specific services:
IStorageMigrationService- Migration orchestrationIPathTransformationService- Path/name transformations between providersKey Interfaces
Implementation Phases
Phase 1: Core Commands (MVP)
tom storage list- Discover available providerstom storage validate- Health check current storagetom storage info- Show current configurationEffort: 2-3 days
Value: Immediate visibility and diagnostics
Phase 2: Provider Switching
tom storage switch- Change provider interactivelyEffort: 2-3 days
Value: Enable post-setup provider changes
Phase 3: Data Migration
tom storage migrate- Full migration workflowIStorageMigrationServiceimplementationEffort: 4-5 days
Value: Seamless data portability
Phase 4: Advanced Features (Future)
tom storage repair- Fix common issuesEffort: TBD
Value: Power user features
Testing Requirements
Following critical path testing approach from #44:
Unit Tests (per use case)
ListProviders.cs Tests:
ValidateStorage.cs Tests:
SwitchProvider.cs Tests:
MigrateStorage.cs Tests:
GetStorageInfo.cs Tests:
Integration Tests
StorageManagementWorkflowTests.cs:
CLI Tests
StorageCommandsTests.cs:
Configuration Impact
No changes to
StorageOptions- this feature only reads configuration and updates via standard mechanisms.Configuration Update Strategy:
IConfigurationto update~/.tom/config/tom-config.jsonUser Experience Considerations
Interactive vs Non-Interactive
Interactive Mode (default):
Non-Interactive Mode (CI/CD, scripting):
--forceskips confirmation prompts--dry-runavailable for previewError Handling
Clear error messages:
Graceful degradation:
--helpfor self-serviceProgress Indicators
Use Spectre.Console for rich CLI experience:
Documentation Updates
README.md
Add new section after "Setup":
docs/STORAGE-MANAGEMENT.md (New)
Create comprehensive guide covering:
docs/OBSIDIAN-STORAGE.md
Update "Migrating from Default Storage" section:
Success Criteria
✅ Commands Implemented:
tom storage list- Shows available providerstom storage validate- Validates current storagetom storage info- Shows storage detailstom storage switch- Changes providertom storage migrate- Migrates data✅ Testing:
✅ Documentation:
✅ User Experience:
✅ Backward Compatibility:
Dependencies and Prerequisites
Requires:
Blocks:
Questions and Open Issues
Provider Discovery Enhancement: Should
IStorageProviderFactoryexposeGetAvailableProviders()or should we addIProviderMetadata?Configuration Updates: Should we use
IConfigurationdirectly or create aIConfigurationWriterabstraction?Backup Location: Should backups live in
~/.tom/backups/or within the storage root?Migration Atomicity: Should we implement rollback on partial migration failure?
Concurrent Access: Should we implement file locking during migration to prevent concurrent writes?
Multi-Provider Routing: Phase 4 feature - allow different note types to different providers (e.g., daily → Obsidian, weekly → Default). This would require routing configuration and multi-provider resolution.
Related Issues
Notes
This issue properly applies Vertical Slice Architecture:
IStorageProvider,IStorageProviderFactory, provider implementationsThe feature is self-contained in
src/Features/StorageManagement/and has no cross-dependencies on other features. It only depends on shared infrastructure (IStorageProvider,IOptions<StorageOptions>).