Skip to content

Conversation

StevenTCramer
Copy link
Contributor

@StevenTCramer StevenTCramer commented Sep 17, 2025

This PR implements sequential route matching that preserves AST order, enabling position-sensitive patterns where options must appear at specific positions.

Core Routing Improvements

Sequential Matching Architecture

  • Unified Segments List: Refactored CompiledRoute from split structure (PositionalMatchers + OptionMatchers) to unified Segments list that preserves AST order
  • Hybrid Matching Strategy: Pre-pass for repeated options + sequential matching for other segments
  • Position-Aware Options: Options can now be matched at specific positions (e.g., --detach must appear before -- in docker run --detach -- {*cmd})
  • Backward Compatibility: Maintained via computed properties that filter the unified list

Key Changes

  • CompiledRoute.cs: Changed to unified Segments property with backward-compatible computed properties
  • Compiler.cs: Added ToCamelCase helper to normalize kebab-case option names to valid C# identifiers
  • EndpointResolver.cs: Implemented sequential matching with index tracking for repeated options
  • LoggerMessageDefinitions.cs: Added RequiredOptionValueNotProvided logger message

Test Results

  • ✅ All 80 routing tests passing (100%)
  • ✅ routing-06-repeated-options.cs: 6/6 tests passing
  • ✅ routing-08-end-of-options.cs: 4/4 tests passing
  • ✅ routing-09-complex-integration.cs: 4/4 tests passing

Bug Fixes

  • Parameter Name Normalization: Fixed kebab-case option names (--no-verify) creating invalid C# identifiers, failing to bind with camelCase delegate parameters (noVerify)
  • Repeated Options: Fixed repeated options being matched at specific positions instead of scanning all remaining args
  • Test Pattern: Fixed routing-09 pattern to correctly use --config? {cfg?} for progressive enhancement

Minor MCP Server Updates

  • Updated ValidateRouteTool to work with new unified Segments API

Version

  • Bumped to 2.1.0-beta.12

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

StevenTCramer and others added 30 commits September 17, 2025 09:15
- Add ErrorHandlingTool with methods for error handling info, scenarios, and best practices
- Implement caching with memory and disk cache support
- Add GitHub documentation fetching with fallback content
- Update MCP server registration and documentation
- Add comprehensive test coverage for error handling functionality
- Document .NET SDK dnx symlink issue
- Delete RandomNumberTools.cs
- Remove tool registration from Program.cs
- Update README.md documentation
- Remove and renumber tests in test-mcp-server.cs
This comprehensive task addresses the factorial explosion problem when dealing with
multiple optional options in CLI routes. The solution makes all options inherently
optional (as they should be by definition) and introduces NuruContext for advanced
scenarios requiring access to parse information.

Key changes planned:
- Make all options optional by default (no factorial route definitions needed)
- Add NuruContext for delegates that need full parse information
- Enforce nullable types for option parameters via analyzer rule NURU010
- Update documentation and MCP server to reflect new semantics
- Support both delegate and Mediator command patterns

This aligns Nuru with industry standards (Click, Cobra) where options are optional
and required inputs are positional parameters.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
These tests explore and demonstrate the current behavior of optional options
in Nuru, revealing that:
- Options defined in routes are currently required for the route to match
- This leads to factorial explosion with multiple optional options
- Boolean options are already somewhat optional (default to false)
- The framework needs refactoring to make options truly optional

These tests will be updated/replaced as part of task 013 to reflect the new
desired behavior where all options are optional by default.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Moving task 013_Implement-Optional-Options-and-NuruContext.md from ToDo to InProgress to begin implementation of making options truly optional by default.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…entation

- Created design documents for optional flags and repeated options syntax
- Added test matrix with 12 application-level test files for new patterns
- Created parser tests for optional (?) and repeated (*) modifiers
- Verified lexer already handles ? and * tokens correctly (no changes needed!)
- Fixed project paths in existing parser/lexer tests
- Established baseline test results and documented test status
- Deleted obsolete test using deprecated APIs
- Updated Kanban task with progress

Next: Implement parser support for ? modifier on flags

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Phase 1 Complete - Parser now recognizes optional flag syntax:
- Added IsOptional property to OptionSyntax record
- Updated ParseOption to check for ? token after flag names
- All test patterns with --flag? now parse successfully

Test verified: test-parser-optional-flags.cs passes all valid patterns

Next: Update RouteCompiler to use IsOptional property

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Added IsOptional property to OptionMatcher class
- Updated RouteCompiler to pass IsOptional from OptionSyntax to OptionMatcher
- Maintains backward compatibility with default value of false

This completes Phase 2 of implementing optional options syntax.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Modified CheckRequiredOptions to check IsOptional property on OptionMatcher
- Optional options are now properly skipped when not provided
- Boolean options default to "false" when not provided
- Value options will be null when not provided (handled by binding)
- Added new logger messages for optional option handling

This completes Phase 3 of implementing optional options syntax.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Created 6 new test files for complete coverage:
  - test-required-flag-optional-value.cs: Tests --flag {value?} pattern
  - test-positional-optional-after-required.cs: Tests {required} {optional?} pattern
  - test-catch-all-with-options.cs: Tests {*args} with --flag? patterns
  - test-invalid-positional-patterns.cs: Tests analyzer rules NURU007, NURU008
  - test-typed-parameters.cs: Tests {param:type} patterns
  - test-typed-optional-parameters.cs: Tests {param:type?} patterns

- Moved test-matrix.md to test-matrix folder and updated to show 100% coverage
- Test matrix now covers all features from route-syntax-and-specificity.md
- Made test files executable
- Updated InProgress task with Phase 1-3 completion status

This completes the test coverage needed to validate the optional options
and NuruContext implementation. Many tests will fail until all phases are
complete, but they serve as the specification for the expected behavior.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add support for repeated option parameters with * modifier (--flag {param}*)
- Implement POSIX-compliant -- separator for end-of-options
- Add new TokenType.EndOfOptions for standalone --
- Update parser to validate -- must be followed by catch-all
- Refactor syntax node classes into separate files
- Add comprehensive tests for both features
- Update route-syntax-and-specificity.md documentation
- Update MCP server with new pattern examples and documentation

This enables advanced CLI patterns like:
- docker build --build-arg KEY1=val1 --build-arg KEY2=val2
- exec npm -- run build --watch
- docker exec container -- command with --flags

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add IsRepeated property to ParameterSyntax and OptionMatcher
- Update parser to recognize * modifier for repeated option parameters
- Add EndOfOptions token type to lexer for standalone --
- Update RouteBasedCommandResolver to collect multiple values for repeated options
- Modify matching logic to treat everything after -- as positional arguments
- Update route compiler to pass IsRepeated flag to OptionMatcher
- Add comprehensive documentation for -- separator in route-syntax-and-specificity.md
- Update MCP server tools with repeated and separator pattern examples
- All parser tests passing (15/15 for end-of-options, 21/21 for repeated options)
- All integration tests passing (44/44 for each implementation variant)

🤖 Generated with Claude Code

Co-Authored-By: Claude <[email protected]>
- Extract ParseOptionForms to handle long/short form parsing
- Extract ParseOptionDescription for description parsing
- Extract ParseOptionParameter for parameter parsing
- Reduces ParseOption from ~82 lines to ~27 lines
- No functional changes, all tests still pass

🤖 Generated with Claude Code

Co-Authored-By: Claude <[email protected]>
- Created run-all-tests.cs that discovers and runs all 54 tests
- Uses target-typed new expressions per analyzer requirements
- Supports parallel/sequential execution modes
- Category filtering with --category option
- Verbose output with --verbose flag
- Stop-on-fail mode for quick feedback
- Colored output with pass/fail indicators
- Summary by category and overall statistics
- Lists all failed tests at the end
- Follows strict analyzer rules (var only when apparent, explicit types otherwise)
- Created test organization analysis document recommending library-based structure
…mpilation errors

- Replace raw Process.Start with TimeWarp.Amuru's Shell.Builder
- Properly distinguish between compilation errors (⚠ NO COMPILE) and test failures (✗ FAIL)
- Add WithNoValidation() to handle non-zero exit codes without throwing
- Use CommandOutput from Amuru for structured result handling
- Add using static System.Console to simplify output statements
- Separate compilation errors from test failures in summary report
- Fix async/await pattern throughout the test runner
- Add pragma to test-optional-flag-required-value.cs to fix CA1031
- Create test-status-report.md documenting all test results
- Test now returns 0 (success) when it gets the expected ArgumentException
- Returns 1 (failure) if pattern parses without error or throws wrong exception type
- Add pragma to fix CA1031 compilation error
- Update test-status-report.md: Parser tests now 10/10 (100% PASS)
- Replace old segment types with new Matcher types (LiteralMatcher, ParameterMatcher, OptionMatcher)
- Use PositionalMatchers and OptionMatchers properties from CompiledRoute
- Fix property names (Constraint instead of TypeName, MatchPattern instead of LongForm, etc.)
- Add pragma for CA1031
- Use collection expression syntax for arrays
- Make SplitCommand function static
- All 25 route patterns now parse successfully
- Update test-status-report to remove percentages and just show pass/fail status
- Fixed compilation errors in multiple test files (CA1031, RCS1214, etc)
- Fixed incorrect project paths (../Source/ to ../../../Source/)
- Removed redundant test-four-optional-options.cs (covered by test-matrix)
- Removed redundant test-route-matching.cs (covered by test-all-routes.cs)
- Fixed test-boolean-option.cs to actually test routes
- Updated test-all-routes.cs to use new CompiledRoute API
- Added proper error handling and exit codes to tests
- Exposed bugs:
  - Long form options don't match when alias and description present
  - Catch-all parameters can't have options after them (despite docs)
  - Optional flags not truly optional in many cases
- Created bug tracking tasks in Kanban/ToDo

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Modified test-interception-patterns.cs to remove unimplemented NuruContext
- Deleted test-nurucontext.cs as NuruContext is not planned for implementation
- Started test reorganization with TimeWarp.Nuru.Tests folder structure
- Fixed string interpolation warnings in test-interception-patterns.cs

Tests now reflect actual implemented functionality rather than aspirational features.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…atterns

- Removed async from catch-all route handler (not needed without NuruContext)
- Fixed string interpolation warnings
- Test still exposes catch-all with options bug

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Renamed test-lexer-only.cs to test-route-pattern-tokenization.cs for clarity
- Moved from SingleFileTests/Lexer to TimeWarp.Nuru.Tests/Lexer directory
- Better name describes what the test actually does: tokenizing route patterns

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Test runner now searches both SingleFileTests/Lexer and TimeWarp.Nuru.Tests/Lexer
- Ensures test-route-pattern-tokenization.cs is included in test runs
- Uses collection spread syntax for cleaner code

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Renamed from test-lexer-double-dash-separator.cs to test-end-of-options-separator.cs
- Name now clearly indicates it tests the POSIX -- separator (EndOfOptions token)
- Moved to Tests/TimeWarp.Nuru.Tests/Lexer/ for better organization
- Distinguishes from DoubleDash token used for options like --help

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Renamed from test-lexer-optional-modifiers.cs to test-modifier-tokenization.cs
- Better name reflects that it tests both optional (?) and repeated (*) modifiers
- Moved to Tests/TimeWarp.Nuru.Tests/Lexer/ for consistent organization
- Tests modifier tokenization for flags, parameters, and combined patterns

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Status file no longer needed after test reorganization
- Lexer tests have been moved to TimeWarp.Nuru.Tests/Lexer

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Extracted compound identifier tests from comprehensive test
- Tests identifiers with dashes (dry-run, no-edit, etc.)
- Two tests currently fail: trailing dash and double dash within identifier
- Shows actual lexer behavior vs expected behavior

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Defines what patterns should produce Invalid tokens
- Clarifies that test--case and test- should be invalid
- Distinguishes between valid compound identifiers (dry-run) and malformed patterns
- Provides decision tree for tokenization logic
- Fills gap in documentation about lexer-level validation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Tests patterns that should produce Invalid tokens per lexer design
- Shows 8 failing tests where lexer doesn't match design specification
- Validates that valid patterns don't produce Invalid tokens
- Documents expected behavior for malformed patterns like test--case and test-

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
StevenTCramer and others added 23 commits October 6, 2025 02:23
…unning tests in TestRunner. Refactored into separate InvokeSetup<T>() method for cleaner code.
…cture

- Add TimeoutAttribute for test method timeout enforcement
- Refactor TestHelpers output methods (TestPassed, TestFailed, TestSkipped) with cleaner formatting
- Add async CleanUp support via InvokeCleanup<T>() method
- Implement timeout handling in RunTest using Task.WhenAny pattern
- Standardize Console output with 'using static System.Console' for cleaner WriteLine calls
- Consolidate exception reporting into single-line TestFailed output

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
… CleanUp

- Standardize indentation to 2 spaces across all test files
- Migrate CleanUp methods to async Task signature for consistency
- Add Setup invocation logging in discovery tests
- Remove redundant test ID prefixes (DISC-01, SKIP-02, etc.) from doc comments
- Improve readability with consistent code structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add ClearRunfileCache() and ClearAllRunfileCaches() methods to TestHelpers for managing .NET runfile compilation cache. Enables tests to force fresh compilation when needed, particularly useful for cache invalidation test scenarios.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Switch from dual routes (default route + --tag route) to single route using optional flag syntax: "--tag? {tag?}". Remove commented-out legacy test files that have been migrated to new structure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…e patterns

Add comprehensive test coverage for:
- "--flag? {value}" pattern (optional flag, required value if present)
- "--flag? {value?}" pattern (both flag and value optional)

Update test plan to clarify supported patterns and use cases per syntax-rules.md and parameter-optionality.md design documents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add route-pattern-anatomy.md as the authoritative visual breakdown of all pattern syntax elements with "kitchen sink" example using every feature. Includes:
- Complete terminology hierarchy
- Visual pattern breakdown diagram
- Comprehensive terminology table
- Formal EBNF-style grammar

Update cross-references across parameter-optionality.md, syntax-rules.md, and ubiquitous-language.md to establish route-pattern-anatomy.md as the central reference for pattern terminology. Expand ubiquitous-language.md Parser subsystem with 40+ formally defined terms.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace `var builder = new NuruAppBuilder()` with `NuruAppBuilder builder = new()` throughout codebase for better type visibility. Updated in README, samples, tests, and documentation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add 11 new routing tests covering:
- Basic route matching and parameter binding
- Optional parameters and catch-all patterns
- Option matching and repeated options
- Route selection and end-of-options marker
- Complex integration scenarios and error cases
- Delegate vs Mediator pattern comparison

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add TimeWarp.Mediator package reference and global using to support routing-11-delegate-mediator test that compares both routing approaches.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Add routing test files to kijaribu test runner
- Update InternalsVisibleTo.g.cs with routing test assemblies
- Remove obsolete test-parser-mixed-modifiers assembly reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Format MatchPositionalSegments method signature with vertical alignment for better readability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Fix three critical bugs in catch-all parameter handling:

1. Start position bug: Changed from template index `i` to args position
   `consumedArgs` when collecting catch-all arguments. This was causing
   catch-all to start reading from wrong position after consuming literals.

2. End position bug: Changed from `i + catchAllArgs.Count` to `j` for
   tracking consumed args. The variable `i` is template position, not args
   position.

3. Empty array bug: Always store catch-all value in extractedValues (even
   when empty) to prevent "No value provided for required parameter" error
   in DelegateExecutor.

4. Option filtering bug: Changed catch-all to only stop at *defined* options
   in the route pattern, not all dash-prefixed arguments. This allows
   patterns like `docker run {*cmd}` to capture option-like arguments such
   as `--port 8080` when no options are defined in the route.

Added IsDefinedOption helper to check if an argument matches a defined
option in the route's OptionMatchers collection.

Tests: All 5 catch-all routing tests now pass (was 1/5).

Fixes alignment with design doc syntax-rules.md lines 426-431 which show
catch-all capturing option-like arguments when route has no defined options.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…gments

Reduce cyclomatic complexity from ~12 to ~4 by extracting three focused methods:

1. HandleCatchAllSegment (complexity ~3)
   - Collects remaining arguments for catch-all parameters
   - Stops at defined options in route pattern
   - Returns new consumed args position

2. ValidateSegmentAvailability (complexity ~4)
   - Checks if enough arguments exist
   - Handles optional parameter skipping
   - Returns enum: Proceed/Skip/Fail

3. MatchRegularSegment (complexity ~3)
   - Matches literal or parameter segments
   - Extracts values into dictionary
   - Logs matching results

Benefits:
- Each method has single responsibility
- Easier to test individual behaviors
- Better readability and maintainability
- Reduced cognitive load when debugging

Added SegmentValidationResult enum for clear validation outcomes.

Tests: All routing tests pass (02, 03, 04 verified).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…inations

Add two parser validations that were missing:
- Reject parameter identifiers starting with digits (e.g., {123abc})
- Reject combined catch-all and optional modifiers (e.g., {*files?})

Changes:
- Add InvalidIdentifierError for identifiers not starting with letter/underscore
- Add InvalidModifierCombinationError for conflicting * and ? modifiers
- Add IsValidIdentifier helper to validate identifier format
- Add validation checks in ParseParameter method

Fixes parser-13-syntax-errors.cs test failures (now 6/6 passing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add comprehensive support for all 4 option/parameter optionality combinations
defined in the design document, enabling fine-grained control over CLI patterns.

**The Four Behaviors:**
1. `--config {mode}` - Required flag + Required value
2. `--config {mode?}` - Required flag + Optional value (flag must exist, value optional)
3. `--config? {mode?}` - Optional flag + Optional value (fully optional)
4. `--config? {mode}` - Optional flag + Required value (if provided, must have value)

**Root Cause Analysis:**
The system was missing a way to distinguish between "option expects A value"
(ExpectsValue) and "option's value is optional" (ParameterIsOptional). This
caused routes like `--config {mode?}` to fail when invoked as `build --config`
(flag without value).

**Changes:**

Core Infrastructure:
- Add ParameterIsOptional property to OptionMatcher to track {param?} modifier
- Update Compiler to propagate ParameterSyntax.IsOptional during compilation
- Fix EndpointResolver to match routes when optional values are omitted
- Fix DelegateExecutor to bind null for missing optional values (replace fragile string parsing)

Tests & Documentation:
- Add 9 new comprehensive test cases covering all option behaviors (20/20 passing)
- Add coverage matrix to routing-test-plan.md showing all combinations
- Remove incorrect "NOT SUPPORTED" documentation for --flag? {param?} syntax
- Clean up test runner script (remove duplicate Kijaribu self-test section)

**Impact:**
Enables real-world CLI patterns like:
- `deploy --verbose` (optional level) - flag must exist, level optional
- `build --config? {file}` - config optional, but if provided needs filename
- Progressive enhancement patterns from design doc now fully functional

Fixes #[issue] if applicable

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Extract SyntaxVisitor<T> abstract base class from ISyntaxVisitor.cs into its own file for better code organization. This follows the Single Responsibility Principle by separating the interface definition from the base implementation.

Changes:
- Create SyntaxVisitor.cs with the abstract base class
- Keep ISyntaxVisitor.cs focused on the interface definition only
- Remove duplicate using statement

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…t-match selection

Implement complete specificity-based routing system that enables progressive interception patterns for gradually wrapping/intercepting existing commands.

**Specificity Scoring (Compiler.cs)**
Update scoring to match design specification (documentation/developer/design/resolver/specificity-algorithm.md):
- Literals: 100 points (was 15)
- Required options: 50 points (was 10)
- Optional options: 25 points (new)
- Typed parameters: 20 points (was 2)
- Untyped parameters: 10 points (was 2)
- Optional parameters: 5 points (new)
- Catch-all: 1 point (was -20)

Add differentiation for:
- Typed vs untyped positional parameters
- Optional vs required parameters
- Required vs optional option flags
- Boolean flags score as required (50pts) for specificity while remaining optional at runtime

**Best Match Selection (EndpointResolver.cs)**
Change from "first match wins" to comprehensive best-match selection:
- Collect ALL matching routes (not just first)
- Track defaults used per match (new RouteMatch record)
- Rank by: fewer defaults → higher specificity → first registered
- Return best match

This enables progressive interception where specific handlers intercept exact patterns while general handlers catch everything else. Example:
- `deploy {env} --tag {t} --verbose` intercepts only WITH --verbose
- `deploy {env} --tag {t}` intercepts --tag requests without --verbose
- `deploy {env}` intercepts simple deploys

When running `deploy prod --tag v1.0`:
- Route with --verbose matches with verbose=false (1 default)
- Route without --verbose matches exactly (0 defaults) ← WINS

**Test Fixes (routing-07-route-selection.cs)**
- Fix parameter names to match route patterns (name-based binding requirement)
- Add pragma to suppress unused parameter warnings
- All 8/8 route selection tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add support for typed arrays in repeated options (int[], double[], etc.) and improve test infrastructure.

**Array Type Conversion (DelegateExecutor.cs)**
- Implement element-wise type conversion for non-string arrays
- Use TypeConverterRegistry first, fallback to Convert.ChangeType
- Support all standard types (int, double, DateTime, etc.)
- Provide clear error messages when conversion fails

**Test Infrastructure**
- Add TimeWarp.Nuru.Logging reference to test projects for UseDebugLogging() support
- Add [ClearRunfileCache] attribute to routing-06-repeated-options.cs

Example usage:
```csharp
builder.AddRoute("process --id {id:int}*", (int[] id) => ...);
// Handles: process --id 1 --id 2 --id 3
// Binds to: int[] { 1, 2, 3 }
```

All 6/6 repeated options tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Refactors route matching from two-pass (positionals then options) to sequential
matching that preserves AST segment order. This enables position-sensitive
patterns like 'docker run --detach -- {*cmd}' where option placement matters.

Key changes:
- CompiledRoute: unified Segments list replaces separate PositionalMatchers/OptionMatchers
- Compiler: builds single ordered segment list matching AST structure
- EndpointResolver: hybrid matching strategy
  - Pre-pass: repeated options scan all args, mark consumed indices
  - Sequential: literals, parameters, and non-repeated options match in order
  - Index tracking: ensures accurate total consumption count

Fixes routing-08-end-of-options.cs (4/4 tests passing)
Maintains routing-06-repeated-options.cs (6/6 tests passing)
Overall: 78/80 routing tests passing (2 failures are pre-existing parameter binding bug)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…iers

Boolean options like `--no-verify` were creating parameter names with dashes
(`no-verify`) which are invalid C# identifiers, causing parameter binding to
fail when delegate parameters use camelCase (`noVerify`).

Solution: Add ToCamelCase helper that strips dashes/underscores and lowercases
the first character when setting boolean option parameter names.

Also fixes routing-09 test pattern: `--config {cfg?}` was incorrectly treating
the option flag as required. Changed to `--config? {cfg?}` to make both the
option and its parameter optional, matching the progressive enhancement intent.

Fixes routing-09-complex-integration.cs (4/4 tests passing, was 2/4)
Overall: 80/80 routing tests now passing (100%!)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Adapts to CompiledRoute refactoring that replaced RequiredOptionPatterns and
MinimumRequiredArgs properties with unified Segments list.

Changes:
- Compute required options by filtering OptionMatchers where !IsOptional
- Calculate minimum required args by counting non-optional PositionalMatchers

Maintains backward compatibility for MCP route validation functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@StevenTCramer StevenTCramer changed the title MCP Server Improvements feat: implement sequential route matching with position-aware options Oct 7, 2025
StevenTCramer and others added 5 commits October 7, 2025 15:58
Move TimeWarp.Nuru.TestApp.Delegates and TimeWarp.Nuru.TestApp.Mediator
to Tests/TestApps/ subdirectory with its own Directory.Build.props that
excludes Kijaribu test framework.

TestApps are CLI applications being tested, not test runners - they don't
need Kijaribu which was causing AOT trimming errors (IL2090) due to
reflection usage in test discovery.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Update all paths in test-both-versions.sh from Tests/TimeWarp.Nuru.TestApp.*
to Tests/TestApps/TimeWarp.Nuru.TestApp.* to reflect the directory restructuring.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Update project paths in TimeWarp.Nuru.slnx from Tests/TimeWarp.Nuru.TestApp.*
to Tests/TestApps/TimeWarp.Nuru.TestApp.* to reflect the directory restructuring.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Update TestApp project paths in Build.cs from Tests/TimeWarp.Nuru.TestApp.*
to Tests/TestApps/TimeWarp.Nuru.TestApp.* to reflect the directory restructuring.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@StevenTCramer StevenTCramer merged commit 486a4e9 into master Oct 7, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant