ryo-suggest 0.1.0

[experimental] Pattern-based suggestion engine for RYO
Documentation
//! RYO Suggest - Continuous refactoring suggestion engine
//!
//! This crate provides code improvement suggestions through pattern detection
//! and generates MutationSpecs for execution via ryo-executor.
//!
//! # Architecture
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────────┐
//! │  Suggest Domain Layer                                           │
//! │  ───────────────────                                            │
//! │  SuggestRegistry        SuggestStore         SuggestService     │
//! │    ├─ register()          ├─ insert()          ├─ query()       │
//! │    ├─ get()               ├─ get()             ├─ detect()      │
//! │    └─ by_category()       └─ gc()              └─ to_specs()    │
//! │           ↓                    ↓                     ↓          │
//! │  Suggest.detect() → SuggestOpportunity → MutationSpec           │
//! └─────────────────────────────────────────────────────────────────┘
//! ```
//!
//! # Usage
//!
//! ```ignore
//! use ryo_suggest::{
//!     SuggestService, SuggestRegistry, SuggestQuery,
//!     Suggest, SuggestCategory, SafetyLevel,
//! };
//!
//! // Create registry and register patterns
//! let mut registry = SuggestRegistry::new();
//! registry.register(MyPattern::new());
//!
//! // Create service
//! let service = SuggestService::new(registry);
//!
//! // Detect suggestions
//! let count = service.detect(&ctx, &symbols);
//!
//! // Query suggestions
//! let auto_safe = service.query(
//!     &SuggestQuery::all().with_max_safety(SafetyLevel::Auto)
//! );
//!
//! // Generate mutation specs
//! for (id, _, _) in auto_safe {
//!     if let Some(specs) = service.to_mutation_specs(id, &ctx) {
//!         // Execute specs via ryo-executor...
//!     }
//! }
//! ```
//!
//! # Key Components
//!
//! - [`Suggest`] - Trait for implementing detection patterns
//! - [`SuggestRegistry`] - Registration and lookup for Suggest implementations
//! - [`SuggestStore`] - Lifecycle management with generation-based invalidation
//! - [`SuggestService`] - Thread-safe service with RwLock for concurrent access
//! - [`SuggestStrategy`] - Control re-evaluation timing (PerGoal/PerWave/Manual)
//! - [`IntentLockQuery`] / [`IntentLockOps`] - Dirty read prevention traits
//!
//! # Spec Suggests
//!
//! ## Implemented (Problem Detection)
//!
//! | Code | Name | Category | Safety | Description |
//! |------|------|----------|--------|-------------|
//! | RS001 | `MissingSpecForDomainType` | Lint | Confirm | Detect domain types without Spec TypeAlias |
//! | RS002 | `OrphanSpec` | Refactor | Confirm | Detect unused Spec TypeAliases |
//! | RS003 | `InvalidSpecRelation` | Lint | Manual | Detect SpecRelation targets that don't exist |
//! | RS004 | `SpecGroupInconsistency` | Lint | Manual | Detect mixed Groups in same module |
//! | RS005 | `SpecRelationCycle` | Lint | Manual | Detect circular dependencies in SpecRelations |
//! | RS006 | `MissingRelation` | Pattern | Confirm | Suggest Relations based on struct field types |
//!
//! ## Implemented (Spec-Driven)
//!
//! | Code | Name | Category | Safety | Description |
//! |------|------|----------|--------|-------------|
//! | RS007 | `SpecRelationToField` | Pattern | Confirm | Spec relation → struct field suggestion |
//! | RS008 | `BidirectionalRelation` | Pattern | Confirm | Ensure bidirectional Spec relations |
//!
//! ## Future Candidates (Spec-Driven)
//!
//! | Code | Name | Category | Description |
//! |------|------|----------|-------------|
//! | RS009 | `SpecDrivenMethod` | Pattern | Spec relation → accessor method suggestion |
//! | RS010 | `SpecGroupTrait` | Pattern | Group → common trait implementation |
//! | RS011 | `SpecDrivenRepository` | Pattern | Spec → Repository trait generation |
//!
//! # Performance Suggestions
//!
//! | Code | Name | Category | Safety | Description |
//! |------|------|----------|--------|-------------|
//! | RP001 | `UnnecessaryClone` | Performance | Confirm | Detect clone() where ownership is not needed |
//!
//! # Safety Suggestions
//!
//! | Code | Name | Category | Safety | Description |
//! |------|------|----------|--------|-------------|
//! | RS101 | `UnwrapToExpect` | Safety | Confirm | Convert unwrap() to expect() with descriptive message |
//! | RS102 | `StringErrorType` | Safety | Manual | Detect string-based error types, suggest thiserror |
//!
//! ## Spec-First Generation (Planned)
//!
//! For greenfield development, a different approach is needed:
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────────┐
//! │  Spec-First Generation (vs Problem Detection)                   │
//! │  ─────────────────────────────────────────────                  │
//! │                                                                 │
//! │  Problem Detection (current):                                   │
//! │    Code → detect() → Problems → MutationSpec                    │
//! │                                                                 │
//! │  Spec-First Generation (planned):                               │
//! │    Spec Definition → generate() → New Code                      │
//! │                                                                 │
//! │  Use Cases:                                                     │
//! │    - New domain model from Spec                                 │
//! │    - Scaffold struct/fields/methods from Spec relations         │
//! │    - Generate Repository/Service patterns from Spec Group       │
//! └─────────────────────────────────────────────────────────────────┘
//! ```

mod allow;
pub mod design_choice;
pub mod enhanced;
pub mod generator;
mod id;
pub mod intent_lock;
pub mod lint;
pub mod pattern;
pub mod performance;
pub mod safety;
mod service;
pub mod spec;
mod store;
mod suggest;
mod suggest_registry;
mod trigger;

// ========== Core Exports ==========
pub use allow::AllowStore;
pub use id::{ParseSuggestIdError, SuggestId, SuggestIdGenerator};
pub use intent_lock::{IntentId, IntentLockOps, IntentLockQuery, LockError, NoOpIntentLock};
pub use service::{
    DetectWithPrecheckResult, ParameterizedSuggestInfo, SuggestQuery, SuggestService, SuggestStats,
    SuggestView,
};
pub use store::{GcConfig, PrecheckStatus, StoredSuggestion, SuggestIndex, SuggestStore};
pub use suggest::{
    compute_priority, EnumToTraitStrategy, LintSeverity, MatchHandling, MutationSpec,
    OpportunityContext, OpportunityId, ParamDef, SafetyLevel, Suggest, SuggestBox, SuggestCategory,
    SuggestError, SuggestLocation, SuggestOpportunity, SuggestParams, SuggestResult, SymbolScope,
};
pub use suggest_registry::SuggestRegistry;
pub use trigger::{
    AcChanges, EvalGranularity, GoalId, PendingChanges, SuggestStrategy, SuggestTrigger,
    TriggerKind, WaveId,
};

// Pattern integration
pub use pattern::{PatternBasedSuggest, RuleScope, RuleStore, RuleStoreError};

// ========== Enhanced Suggestions ==========
pub use design_choice::{ChoiceId, DesignChoice, DesignChoiceSet, Rating, TradeOffs};
pub use enhanced::{ApplyCommands, EnhancedSuggestion, VerificationStatus, VerifiedCandidate};

// ========== Spec Suggestions ==========
pub use spec::{
    BidirectionalRelation, InvalidSpecRelation, MissingRelation, MissingSpecForDomainType,
    OrphanSpec, SpecGroupInconsistency, SpecRelationCycle, SpecRelationToField,
};

// ========== Parameterized Suggestions (Code Generation) ==========
pub use spec::{ApiPatternSuggest, DomainStructSuggest};

// ========== Spec Generators ==========
pub use spec::{DomainSpecGenerator, GeneratorOptions, SpecGenerator, SpecGeneratorRegistry};

// ========== Generator Templates (User-defined) ==========
pub use generator::{
    GeneratorEntry, GeneratorLoadError, GeneratorLoader, GeneratorMeta, GeneratorScope,
    GeneratorStore, GeneratorStoreError, GeneratorTemplate, InsertPosition, ParamSpec, RenderError,
    TemplateSpec,
};

// ========== Performance Suggestions ==========
pub use performance::{PerformanceSuggest, UnnecessaryClone};

// ========== Safety Suggestions ==========
pub use safety::{SafetySuggest, StringErrorType, UnwrapToExpect};