Skip to content

CommandConfig Contract & Parser Refactoring #91

Description

@rucka

Resolution

Delivered by PR #96 (merged). Board: Done.

feat: CommandConfig Contract & Parser Refactoring.

Story Statement

As a CLI developer
I want refactored command parsing with explicit CommandConfig discriminated union types organized by command
So that KB source resolution logic is type-safe, testable, and maintains clear contracts between CLI parsing and configuration building with proper dispatch to command handlers

Where: apps/pair-cli/src/commands/{command}/ (parser.ts, handler.ts, index.ts per command) with shared helpers

Epic Context

Parent Epic: #65 Enhanced CLI Packaging & Distribution
Status: Refined
Priority: P0 (Must-Have)

Status Workflow

  • Refined: Story is detailed, estimated, and ready for development
  • In Progress: Story is actively being developed ✅ Current
  • Done: Story delivered and accepted

Acceptance Criteria

Functional Requirements

Given-When-Then Format:

  1. Given user runs pair install (no flags)
    When command parser executes
    Then parser creates InstallCommandConfig with default resolution detected (monorepo or release)

  2. Given user runs pair install --source https://example.com/kb.zip
    When command parser executes
    Then parser creates InstallCommandConfig with remote URL source

  3. Given user runs pair install --source /absolute/path/to/kb
    When command parser executes
    Then parser creates InstallCommandConfig with local directory source

  4. Given user runs pair install --offline --source ./local/kb
    When command parser executes
    Then parser creates InstallCommandConfig with offline mode enabled and local source

  5. Given user runs pair install --offline (no --source)
    When command parser executes
    Then parser throws validation error "Offline mode requires explicit --source with local path"

  6. Given user runs pair install --offline --source https://example.com/kb.zip
    When command parser executes
    Then parser throws validation error "Cannot use --offline with remote URL source"

  7. Given user runs pair update --source https://example.com/kb.zip
    When command parser executes
    Then parser creates UpdateCommandConfig with remote URL source

  8. Given user runs pair update-link --dry-run
    When command parser executes
    Then parser creates UpdateLinkCommandConfig with dry-run mode enabled

  9. Given user runs pair kb validate
    When command parser executes
    Then parser creates KbValidateCommandConfig with default settings

  10. Given user runs pair kb package --output dist/kb.zip
    When command parser executes
    Then parser creates KbPackageCommandConfig with output path specified

  11. Given user runs pair config validate
    When command parser executes
    Then parser creates ConfigValidateCommandConfig with default settings

  12. Given CommandConfig is union of command-specific types
    When TypeScript type checking occurs
    Then compiler enforces correct properties for each command type (discriminated union)

  13. Given config builder receives InstallCommandConfig with default resolution
    When config builder executes
    Then builder calls getKnowledgeHubDatasetPath() only if in monorepo pair context

  14. Given KB manager needs KB source
    When handler dispatches based on CommandConfig type
    Then appropriate handler (install/update/kb-validate/kb-package/update-link/config-validate) executes with correct configuration

  15. Given helper function detectSourceType(source: string) is called
    When evaluating a source string
    Then function returns 'remote' | 'local' based on URL prefix check (http/https) without modifying the CommandConfig type structure

Business Rules

  • CommandConfig is discriminated union organized by command type (InstallCommandConfig, UpdateCommandConfig, KbValidateCommandConfig, KbPackageCommandConfig, UpdateLinkCommandConfig, ConfigValidateCommandConfig)
  • Each command has specific config shape with command discriminator field identifying the command
  • No optional parameters - use union types and discriminators instead of optional fields
  • Source type detection happens via helper function detectSourceType(), not as a type field
  • Parser validates before creating CommandConfig - invalid combinations throw early with clear errors
  • --offline flag only valid with local source (directory or ZIP file)
  • Relative paths resolved at config builder level, not in parser (parser stores raw input)
  • getKnowledgeHubDatasetPath() called only when in monorepo pair context with default resolution
  • Command dispatch happens via handlers organized by command type using exhaustiveness checking
  • Parser is pure function - no file system access, no network calls, only argument transformation
  • Default source detection (monorepo vs release) happens in config builder, not parser

Edge Cases and Error Handling

  • --offline with remote URL: Parser validation error "Cannot use --offline with remote URL source"
  • --offline without --source: Parser validation error "Offline mode requires explicit --source with local path"
  • Empty --source value: Parser validation error "Source path/URL cannot be empty"
  • Invalid URL format: Detected by helper function detectSourceType(), creates appropriate config variant
  • Conflicting flags: Parser validates all flag combinations before creating CommandConfig

Technical Analysis

Implementation Approach

Technical Strategy: Refactor command parsing into pure functions that transform CLI arguments into well-typed CommandConfig objects using TypeScript discriminated unions. Use helper functions for source type detection. Organize code by command in dedicated folders with parser and handler modules.

Architecture Overview:

apps/pair-cli/src/
├── commands/
│   ├── helpers.ts                  # detectSourceType, validateCommandOptions
│   ├── install/
│   │   ├── parser.ts               # parseInstallCommand, InstallCommandConfig type
│   │   ├── handler.ts              # handleInstallCommand
│   │   └── index.ts                # Exports parser function, handler, config type
│   ├── update/
│   │   ├── parser.ts               # parseUpdateCommand, UpdateCommandConfig type
│   │   ├── handler.ts              # handleUpdateCommand
│   │   └── index.ts                # Exports parser function, handler, config type
│   ├── kb-validate/
│   │   ├── parser.ts               # parseKbValidateCommand, KbValidateCommandConfig type
│   │   ├── handler.ts              # handleKbValidateCommand
│   │   └── index.ts                # Exports parser function, handler, config type
│   ├── kb-package/
│   │   ├── parser.ts               # parseKbPackageCommand, KbPackageCommandConfig type
│   │   ├── handler.ts              # handleKbPackageCommand
│   │   └── index.ts                # Exports parser function, handler, config type
│   ├── update-link/
│   │   ├── parser.ts               # parseUpdateLinkCommand, UpdateLinkCommandConfig type
│   │   ├── handler.ts              # handleUpdateLinkCommand
│   │   └── index.ts                # Exports parser function, handler, config type
│   ├── config-validate/
│   │   ├── parser.ts               # parseConfigValidateCommand, ConfigValidateCommandConfig type
│   │   ├── handler.ts              # handleConfigValidateCommand
│   │   └── index.ts                # Exports parser function, handler, config type
│   ├── dispatcher.ts               # dispatchCommand with exhaustiveness checking
│   └── index.ts                    # Exports: CommandConfig union, all parsers, dispatcher
├── cli.ts                           # Commander.js definitions (updated)
├── config-utils.ts                  # Config builders (refactored)
└── index.ts

Key Components:

  1. CommandConfig Type Definitions (apps/pair-cli/src/commands/{command}/parser.ts)

    • InstallCommandConfig - install command configuration
    • UpdateCommandConfig - update command configuration
    • KbValidateCommandConfig - kb validate command configuration
    • KbPackageCommandConfig - kb package command configuration
    • UpdateLinkCommandConfig - update-link command configuration
    • ConfigValidateCommandConfig - config validate command configuration
    • Each has a command discriminator field
    • Root CommandConfig = union of all command types (in commands/index.ts)
  2. Helper Functions (apps/pair-cli/src/commands/helpers.ts)

    • detectSourceType(source: string): 'remote' | 'local' - URL vs path detection
    • validateCommandOptions(command, options): void - shared validation logic
    • Pure utility functions, no side effects
  3. Command Parsers (apps/pair-cli/src/commands/{command}/parser.ts)

    • parseInstallCommand(options): InstallCommandConfig - pure function
    • parseUpdateCommand(options): UpdateCommandConfig - pure function
    • parseKbValidateCommand(options): KbValidateCommandConfig - pure function
    • parseKbPackageCommand(options): KbPackageCommandConfig - pure function
    • parseUpdateLinkCommand(options): UpdateLinkCommandConfig - pure function
    • parseConfigValidateCommand(options): ConfigValidateCommandConfig - pure function
    • Each uses helper functions for type detection
    • Each exports its CommandConfig type definition
  4. Command Handlers (apps/pair-cli/src/commands/{command}/handler.ts)

    • handleInstallCommand(config): Promise - process InstallCommandConfig
    • handleUpdateCommand(config): Promise - process UpdateCommandConfig
    • handleKbValidateCommand(config): Promise - process KbValidateCommandConfig
    • handleKbPackageCommand(config): Promise - process KbPackageCommandConfig
    • handleUpdateLinkCommand(config): Promise - process UpdateLinkCommandConfig
    • handleConfigValidateCommand(config): Promise - process ConfigValidateCommandConfig
    • Handlers orchestrate config building and execution
  5. Command Module Exports (apps/pair-cli/src/commands/{command}/index.ts)

    • Exports parser function, handler function, and CommandConfig type
    • Clean public API for each command module
  6. Command Dispatcher (apps/pair-cli/src/commands/dispatcher.ts)

    • dispatchCommand(config): Promise - route by command type using exhaustiveness checking
    • Switch statement with all command types covered
    • TypeScript compiler validates all variants handled
  7. Config Builders (config-utils.ts - refactored)

    • Accept CommandConfig variants instead of raw options
    • Dispatch based on config command type
    • Delegate to existing path resolution for default resolution
    • Handle remote/local sources explicitly
    • Call getKnowledgeHubDatasetPath() only in monorepo pair context
  8. CLI Integration (cli.ts)

    • Import and use parser functions for each command
    • Error handling for parser validation failures
    • Pass CommandConfig to dispatcher

Data Flow:

CLI Arguments (Commander.js)
  ↓
parseInstallCommand(options) → validation → InstallCommandConfig
  ↓
dispatchCommand(config) → handleInstallCommand(config)
  ↓
buildInstallOptions(config) → InstallOptions
  ↓
executeInstall(installOptions)

Module Organization Rationale:

  • commands/{command}/parser.ts: Type definitions and pure parser functions
  • commands/{command}/handler.ts: Business logic execution
  • commands/{command}/index.ts: Public exports (parser, handler, types)
  • commands/helpers.ts: Shared utilities (detectSourceType, validation)
  • commands/dispatcher.ts: Central command routing with exhaustiveness checking
  • commands/index.ts: Root exports (CommandConfig union, all parsers, dispatcher)
  • cli.ts: CLI framework integration
  • config-utils.ts: Configuration building (CommandConfig → options)

Helper Function Pattern (instead of type field):

// commands/helpers.ts - pure utility function
function detectSourceType(source: string): 'remote' | 'local' {
  return /^https?:\/\//i.test(source) ? 'remote' : 'local';
}

// Used in parser
const sourceType = detectSourceType(options.source);
if (sourceType === 'remote') {
  return { command: 'install', url: options.source, offlineMode: false };
}
return { command: 'install', path: options.source, offlineMode: options.offline ?? false };

This keeps the CommandConfig type structure clean (no extra fields) while providing source type detection as a utility.

Technical Requirements

  • TypeScript discriminated union organized by command type with strict type checking
  • Parser functions are pure (no side effects, no file I/O, no network)
  • Helper functions for source type detection and validation
  • Comprehensive unit tests for all CommandConfig types and validation scenarios
  • Backward compatibility: existing commands without flags work identically
  • Handler dispatch uses type-safe switch statement with exhaustiveness checking
  • getKnowledgeHubDatasetPath() called only when in monorepo pair context
  • Source type detection via helper function: starts with http:// or https:// → remote, else → local
  • Documentation: JSDoc comments for all public types and functions
  • Module organization supports extensibility for additional commands

Technical Risks and Mitigation

Risk Impact Probability Mitigation Strategy
Breaking changes to existing behavior High Low Comprehensive regression tests, backward compatibility validation
Complex dispatch logic with many commands Medium Low Use exhaustiveness checking, TypeScript compiler validates
getKnowledgeHubDatasetPath() called in release mode High Medium Add guard clause checking if in monorepo context before calling
Module organization confusion Medium Low Clear separation: parser.ts (types+parser), handler.ts (business logic), index.ts (exports)
Parser validation too strict Medium Medium Start permissive, add strictness incrementally based on usage

Definition of Done Checklist

Development Completion

  • InstallCommandConfig discriminated union defined in install/parser.ts
  • UpdateCommandConfig discriminated union defined in update/parser.ts
  • KbValidateCommandConfig type defined in kb-validate/parser.ts
  • KbPackageCommandConfig type defined in kb-package/parser.ts
  • UpdateLinkCommandConfig type defined in update-link/parser.ts
  • ConfigValidateCommandConfig type defined in config-validate/parser.ts
  • Root CommandConfig union type defined in commands/index.ts
  • Helper function detectSourceType() implemented in commands/helpers.ts
  • Helper function validateCommandOptions() implemented in commands/helpers.ts
  • Parser functions implemented (all 6 commands in respective parser.ts files)
  • Handler functions implemented (all 6 commands in respective handler.ts files)
  • Command exports implemented (all 6 commands in respective index.ts files)
  • Command dispatcher implemented in commands/dispatcher.ts with exhaustiveness checking
  • Config builders refactored to accept CommandConfig
  • CLI handlers integrated with parser and dispatcher
  • Commander.js metadata (description, options, examples) extracted and configured dynamically
  • Guard clause added to getKnowledgeHubDatasetPath() call
  • Code follows project TypeScript standards (no any, no non-null assertions)
  • Code review completed and approved
  • Unit tests for all CommandConfig types (30+ tests minimum)
  • Unit tests for all parsers (40+ tests)
  • Unit tests for validation scenarios (invalid combinations)
  • Unit tests for source type detection
  • Unit tests for handler dispatch
  • Integration tests for full parsing flow
  • Regression tests for existing behavior without flags
  • TypeScript compilation with strict mode passes
  • JSDoc comments for all public types and functions

Quality Assurance

  • All acceptance criteria tested and verified
  • Edge cases tested (conflicting flags, empty values, invalid combinations)
  • Backward compatibility verified (existing commands work unchanged)
  • Type safety verified (discriminated union enforces correct properties)
  • Parser purity verified (no side effects in tests)
  • Handler dispatch routing verified (all command types routed correctly)
  • getKnowledgeHubDatasetPath guard verified (not called in release mode)
  • Commander.js help text and options verified (matches metadata)
  • Error messages clear and actionable
  • Code coverage ≥90% for commands/ module
  • Manual testing: all documented scenarios from US KB Source Documentation & CLI Reference #90

Deployment and Release

  • Feature works in both dev and release modes
  • No breaking changes to public CLI interface
  • Documentation (from US KB Source Docs) matches implementation
  • Type definitions exported for potential extension
  • Module organization documented (parser.ts vs handler.ts vs index.ts)
  • Demo-ready: show type safety and dispatch in action

Story Sizing and Sprint Readiness

Final Story Points: 5
Confidence Level: High
Sizing Justification:

  • Type definitions and unions (~1 pt)
  • Parser functions (~1.5 pt)
  • Handler implementation and dispatch (~1.5 pt)
  • Config builder refactoring (~0.5 pt)
  • Comprehensive testing (~0.5 pt)

Sprint Fit Assessment: Yes - fits in 2-3 days of single sprint
Development Time Estimate: 2-2.5 days
Testing Time Estimate: 1 day
Total Effort Assessment: 3-3.5 days total

Dependencies and Coordination

Prerequisite Stories:

Dependent Stories:

Shared Components:

  • cli.ts command definitions
  • config-utils.ts config builders
  • Existing path resolution logic
  • getKnowledgeHubDatasetPath (with added monorepo guard)

Task Breakdown

  • T-1: Define CommandConfig types for all 6 commands (types in respective parser.ts files)
  • T-2: Implement command handlers for all commands in respective handler.ts files
  • T-3: Implement helper functions (detectSourceType, validateCommandOptions)
  • T-4: Implement parser functions for all commands in respective parser.ts files
  • T-5: Implement command module exports in respective index.ts files
  • T-6: Implement command dispatcher with exhaustiveness checking in commands/dispatcher.ts
  • T-7: Refactor config builders to accept CommandConfig and dispatch
  • T-8: Integrate parsers and dispatcher into CLI handlers
  • T-8b: Extract and configure Commander.js metadata (description, options, examples) dynamically
  • T-9: Comprehensive testing (unit, integration, regression)
  • T-10: Documentation and monorepo context guard validation

Total Task Points: 27 pts (task granularity, not story estimate)
Story Estimate: 5 pts (represents cohesive refactoring deliverable)



T-1: Define CommandConfig types for all 6 commands ✅ COMPLETE

Priority: P0 | Estimated Hours: 3h | Bounded Context: Type System & Architecture

Summary: Define command-specific config types for install, update, kb-validate, kb-package, update-link, config-validate commands in their respective parser.ts files.

Type: Feature Implementation

Description: Create types in commands/{command}/parser.ts modules (one per command) with command-specific config types. Each module defines a unique config interface with command discriminator field. Root CommandConfig union type combines all 6 command types in commands/index.ts.

Acceptance Criteria:

  • Primary deliverable: 6 command config type definitions in parser.ts + root CommandConfig union in commands/index.ts
  • Quality standard: TypeScript strict mode compliance, clear discriminator fields
  • Integration requirement: Types exportable for use in handlers and dispatcher
  • Verification method: TypeScript compilation success with strict mode

Technical Requirements:

  • Functionality: Command-specific config types with command discriminator
  • Performance: Zero runtime overhead (compile-time only)
  • Security: N/A
  • Compatibility: TypeScript 5.x

Implementation Approach:

Files to Create:

  • apps/pair-cli/src/commands/install/parser.ts - InstallCommandConfig type + parser
  • apps/pair-cli/src/commands/update/parser.ts - UpdateCommandConfig type + parser
  • apps/pair-cli/src/commands/kb-validate/parser.ts - KbValidateCommandConfig type + parser
  • apps/pair-cli/src/commands/kb-package/parser.ts - KbPackageCommandConfig type + parser
  • apps/pair-cli/src/commands/update-link/parser.ts - UpdateLinkCommandConfig type + parser
  • apps/pair-cli/src/commands/config-validate/parser.ts - ConfigValidateCommandConfig type + parser
  • apps/pair-cli/src/commands/index.ts - Exports root CommandConfig union

Implementation Steps:

  1. Create commands/ directory structure (6 subdirectories, one per command)
  2. Define config type for each command with command discriminator in respective parser.ts
  3. For install/update: variants for source type (determined later by parser via helper)
  4. For kb-validate/kb-package/update-link/config-validate: simple config types
  5. Create root CommandConfig union in commands/index.ts
  6. Add comprehensive JSDoc with examples
  7. TypeScript compilation check

Dependencies:

Technical: None
Tasks: None (independent)

Notes: Source type variants not needed in install/update config types; source type determined at parse-time via helper function


T-2: Implement command handlers for all commands in respective handler.ts files ✅ COMPLETE

Priority: P0 | Estimated Hours: 3h | Bounded Context: Command Execution

Summary: Implement handler functions for all 6 commands that process CommandConfig and orchestrate execution in their respective handler.ts files.

Type: Feature Implementation

Description: Implement handleInstallCommand, handleUpdateCommand, handleKbValidateCommand, handleKbPackageCommand, handleUpdateLinkCommand, handleConfigValidateCommand functions in respective commands/{command}/handler.ts modules. Handlers receive CommandConfig, coordinate config building, and execute command logic. Handlers are entry points for command execution after dispatch.

Acceptance Criteria:

  • Primary deliverable: Handler functions for all 6 commands
  • Quality standard: Clear separation of concerns, proper error handling
  • Integration requirement: Accept CommandConfig variants, delegate to config builders
  • Verification method: Unit and integration tests

Technical Requirements:

  • Functionality: Process CommandConfig, orchestrate execution
  • Performance: No overhead beyond existing handlers
  • Security: N/A
  • Compatibility: Async/await for async operations

Implementation Approach:

Files to Create:

  • apps/pair-cli/src/commands/install/handler.ts
  • apps/pair-cli/src/commands/update/handler.ts
  • apps/pair-cli/src/commands/kb-validate/handler.ts
  • apps/pair-cli/src/commands/kb-package/handler.ts
  • apps/pair-cli/src/commands/update-link/handler.ts
  • apps/pair-cli/src/commands/config-validate/handler.ts

Implementation Steps:

  1. Implement handleInstallCommand(config) with config building and execution
  2. Implement handlers for remaining 5 commands
  3. Add proper error handling and logging
  4. Add JSDoc documentation
  5. Export handlers from respective index.ts files

Dependencies:

Technical: None
Tasks: T-1 (CommandConfig types)

Notes: Handlers delegate to config builders and existing execution logic


T-3: Implement helper functions (detectSourceType, validateCommandOptions) ✅ COMPLETE

Priority: P0 | Estimated Hours: 2h | Bounded Context: Input Validation & Parsing

Summary: Implement utility helper functions for source type detection and command option validation.

Type: Feature Implementation

Description: Create commands/helpers.ts with detectSourceType() and validateCommandOptions() utility functions. detectSourceType() determines if source is remote URL or local path. validateCommandOptions() validates flag combinations before parser creates CommandConfig.

Acceptance Criteria:

  • Primary deliverable: Helper functions with clear separation of concerns
  • Quality standard: Pure functions, accurate detection/validation, clear error messages
  • Integration requirement: Used by all parser functions
  • Verification method: Unit tests for all validation rules and detection cases

Technical Requirements:

  • Functionality: Validate options, detect source type accurately
  • Performance: O(1) complexity
  • Security: Prevent empty/malformed inputs
  • Compatibility: Standard URL formats

Implementation Approach:

Files to Create:

  • apps/pair-cli/src/commands/helpers.ts

Implementation Steps:

  1. Create helpers.ts module
  2. Implement detectSourceType(source: string): 'remote' | 'local' with URL regex
  3. Implement validateCommandOptions(command, options): void with all rules
  4. Add comprehensive error messages
  5. Export functions for parser use
  6. Add JSDoc documentation

Dependencies:

Technical: None
Tasks: None (independent)

Notes: detectSourceType is a pure utility function, not a type field


T-4: Implement parser functions for all commands in respective parser.ts files ✅ COMPLETE

Priority: P0 | Estimated Hours: 4h | Bounded Context: CLI Parsing

Summary: Implement pure parser functions for all 6 commands that transform options into CommandConfig objects in their respective parser.ts files.

Type: Feature Implementation

Description: Implement parseInstallCommand, parseUpdateCommand, parseKbValidateCommand, parseKbPackageCommand, parseUpdateLinkCommand, parseConfigValidateCommand functions in respective commands/{command}/parser.ts modules. Parsers validate options using helpers, handle command-specific logic, return appropriate CommandConfig variant. All parsers are pure functions.

Acceptance Criteria:

  • Primary deliverable: Parser functions for all 6 commands returning proper CommandConfig types
  • Quality standard: Pure functions, comprehensive validation, clear error messages
  • Integration requirement: Accept Commander.js option objects
  • Verification method: Unit tests covering all variants and error scenarios

Technical Requirements:

  • Functionality: Transform options to CommandConfig with validation
  • Performance: O(1) complexity, no file system access
  • Security: Input validation prevents injection
  • Compatibility: Commander.js option format

Implementation Approach:

Files to Modify/Create:

  • apps/pair-cli/src/commands/install/parser.ts
  • apps/pair-cli/src/commands/update/parser.ts
  • apps/pair-cli/src/commands/kb-validate/parser.ts
  • apps/pair-cli/src/commands/kb-package/parser.ts
  • apps/pair-cli/src/commands/update-link/parser.ts
  • apps/pair-cli/src/commands/config-validate/parser.ts

Implementation Steps:

  1. Create parser for install command with option validation
  2. Create parser for update command
  3. Create parsers for remaining 4 commands
  4. Use detectSourceType helper for remote/local detection
  5. Use validateCommandOptions for validation
  6. Add error handling with descriptive messages
  7. Add JSDoc with examples
  8. Export all parsers from commands/index.ts

Dependencies:

Technical: None
Tasks: T-1 (CommandConfig types), T-3 (helper functions)

Notes: Parsers delegate to helpers; validation happens before CommandConfig creation (fail-fast)


T-5: Implement command module exports in respective index.ts files ✅ COMPLETE

Priority: P0 | Estimated Hours: 1h | Bounded Context: Module Exports

Summary: Implement index.ts exports for each command module to expose parser, handler, and types.

Type: Feature Implementation

Description: Create index.ts files in each commands/{command}/ directory. Each index.ts exports the parser function, handler function, and CommandConfig type for that command. This provides a clean public API for each command.

Acceptance Criteria:

  • Primary deliverable: index.ts files with proper exports for all 6 commands
  • Quality standard: Clear public API, no internal details exposed
  • Integration requirement: Used by dispatcher and CLI handlers
  • Verification method: Import tests verify exports work

Technical Requirements:

  • Functionality: Export parser, handler, type cleanly
  • Performance: N/A
  • Security: N/A
  • Compatibility: Standard ES6 exports

Implementation Approach:

Files to Create:

  • apps/pair-cli/src/commands/install/index.ts
  • apps/pair-cli/src/commands/update/index.ts
  • apps/pair-cli/src/commands/kb-validate/index.ts
  • apps/pair-cli/src/commands/kb-package/index.ts
  • apps/pair-cli/src/commands/update-link/index.ts
  • apps/pair-cli/src/commands/config-validate/index.ts

Implementation Steps:

  1. Create index.ts for each command
  2. Export parser function, handler function, and CommandConfig type
  3. Add JSDoc describing what the module exports
  4. Update commands/index.ts to import and re-export all command exports

Dependencies:

Technical: None
Tasks: T-4 (parsers), T-2 (handlers)

Notes: index.ts is the public API surface for each command module


T-6: Implement command dispatcher with exhaustiveness checking in commands/dispatcher.ts ✅ COMPLETE

Priority: P0 | Estimated Hours: 2h | Bounded Context: Command Routing

Summary: Implement dispatcher function that routes CommandConfig to appropriate handler using exhaustiveness checking.

Type: Feature Implementation

Description: Create commands/dispatcher.ts with dispatchCommand() function. Dispatcher uses switch statement on CommandConfig.command field with exhaustiveness checking (assertNever pattern). TypeScript compiler validates all command types are handled.

Acceptance Criteria:

  • Primary deliverable: dispatchCommand function with exhaustiveness checking in commands/dispatcher.ts
  • Quality standard: Type-safe dispatch, clear error handling
  • Integration requirement: Accept all CommandConfig variants
  • Verification method: TypeScript compiler validation, tests

Technical Requirements:

  • Functionality: Route CommandConfig to handler by command type
  • Performance: Minimal overhead
  • Security: N/A
  • Compatibility: TypeScript exhaustiveness checking

Implementation Approach:

Files to Create:

  • apps/pair-cli/src/commands/dispatcher.ts

Implementation Steps:

  1. Create dispatcher.ts module
  2. Implement dispatchCommand(config) with switch on config.command
  3. Add case for each of 6 command types
  4. Add exhaustiveness checking (assertNever for unhandled types)
  5. Add error handling
  6. Add JSDoc documentation
  7. Export dispatcher

Dependencies:

Technical: None
Tasks: T-2 (handler functions), T-5 (command exports)

Notes: assertNever pattern ensures TypeScript compiler validates all variants handled


T-7: Refactor config builders to accept CommandConfig and dispatch ✅ COMPLETE

Priority: P0 | Estimated Hours: 3h | Bounded Context: Configuration Management

Summary: Refactor existing config builder functions to accept CommandConfig and dispatch based on command type.

Type: Refactoring

Description: Modify config-utils.ts builder functions (buildInstallOptions, buildUpdateOptions, etc.) to accept CommandConfig variants. Add guard clause for monorepo context before calling getKnowledgeHubDatasetPath(). Dispatch logic handles each command type.

Acceptance Criteria:

  • Primary deliverable: Refactored config builders accepting CommandConfig
  • Quality standard: Type-safe dispatch, guard for monorepo context, backward compatible
  • Integration requirement: Output unchanged (InstallOptions/UpdateOptions formats)
  • Verification method: Unit and regression tests

Technical Requirements:

  • Functionality: Dispatch by CommandConfig.command, guard monorepo context
  • Performance: No regression
  • Security: N/A
  • Compatibility: Backward compatible output

Implementation Approach:

Files to Modify:

  • apps/pair-cli/src/config-utils.ts

Implementation Steps:

  1. Update buildInstallOptions signature to accept InstallCommandConfig
  2. Add isInPairMonorepo() guard function
  3. Implement switch dispatch on config.command
  4. Handle install command logic with source type dispatch
  5. Update builders for other commands similarly
  6. Update tests to use CommandConfig
  7. Add regression tests for guard behavior

Dependencies:

Technical: None
Tasks: T-1 (CommandConfig types)

Notes: Guard clause critical to prevent getKnowledgeHubDatasetPath() call in release mode


T-8: Integrate parsers and dispatcher into CLI handlers

Priority: P0 | Estimated Hours: 2h | Bounded Context: CLI Integration

Summary: Update CLI command handlers to call parsers and dispatcher with proper error handling.

Type: Feature Implementation

Description: Modify cli.ts command handlers to call appropriate parser function and then dispatchCommand. Add error handling for parser validation failures with user-friendly messages. Maintain backward compatibility.

Acceptance Criteria:

  • Primary deliverable: CLI handlers integrated with parser and dispatcher
  • Quality standard: Clear error messages, graceful failure
  • Integration requirement: Compatible with existing CLI flow
  • Verification method: Integration and manual tests

Technical Requirements:

  • Functionality: Parse → dispatch flow, error handling
  • Performance: No latency increase
  • Security: N/A
  • Compatibility: Existing command-line interface unchanged

Implementation Approach:

Files to Modify:

  • apps/pair-cli/src/cli.ts

Implementation Steps:

  1. Import parsers and dispatcher in cli.ts
  2. Add parser call for each command handler
  3. Add error handling try-catch
  4. Call dispatchCommand with config
  5. Test error messages
  6. Update integration tests

Dependencies:

Technical: None
Tasks: T-4 (parsers), T-6 (dispatcher)

Notes: Exit code 1 for parser errors, 2 for system errors


T-8b: Extract and configure Commander.js metadata dynamically

Priority: P0 | Estimated Hours: 2h | Bounded Context: CLI Metadata & Help

Summary: Extract command metadata (description, options, examples) from existing commands and configure Commander.js dynamically from command modules.

Type: Feature Implementation

Description: Add metadata property to each command module export containing description, usage, examples, and option definitions. Extract help text and option descriptions from existing command implementations. Configure Commander.js dynamically using this metadata instead of hardcoded definitions.

Acceptance Criteria:

  • Primary deliverable: Metadata definitions for all 6 commands with Commander.js dynamic configuration
  • Quality standard: Complete help text, accurate option descriptions, useful examples
  • Integration requirement: Commander.js help command shows correct information
  • Verification method: Manual testing of --help output for all commands

Technical Requirements:

  • Functionality: Metadata drives Commander.js configuration
  • Performance: N/A (configuration happens at startup)
  • Security: N/A
  • Compatibility: Commander.js API

Implementation Approach:

Files to Modify:

  • apps/pair-cli/src/commands/install/index.ts (add metadata)
  • apps/pair-cli/src/commands/update/index.ts (add metadata)
  • apps/pair-cli/src/commands/update-link/index.ts (add metadata)
  • apps/pair-cli/src/commands/package/index.ts (add metadata)
  • apps/pair-cli/src/commands/validate-config/index.ts (add metadata)
  • apps/pair-cli/src/cli.ts (dynamic Commander.js configuration)

Implementation Steps:

  1. Review existing command definitions in cli.ts for current help text and options
  2. Add meta property to each command module export with structure:
    meta: {
      name: string,
      description: string,
      usage?: string,
      examples?: string[],
      options: Array<{ flags: string, description: string, defaultValue?: any }>
    }
  3. Extract all help text, option descriptions, and examples from existing commands
  4. Update cli.ts to configure Commander.js from metadata:
    • Iterate command modules
    • Apply description, usage, examples dynamically
    • Add options from metadata
  5. Test --help output for all commands
  6. Update documentation if needed

Dependencies:

Technical: Commander.js
Tasks: T-5 (command module exports)

Notes: Metadata centralizes CLI documentation; keeps help text with command implementation


T-9: Comprehensive testing (unit, integration, regression)

Priority: P0 | Estimated Hours: 4h | Bounded Context: Quality Assurance

Summary: Implement comprehensive test suite covering all CommandConfig types, parsers, handlers, dispatcher.

Type: Testing

Description: Create test files for commands/ directories. Unit tests for types, parsers, validation, helpers, handlers, dispatcher. Integration tests for full CLI flow. Regression tests for existing behavior.

Acceptance Criteria:

  • Primary deliverable: ≥90% code coverage for commands/ module
  • Quality standard: All edge cases and error scenarios tested
  • Integration requirement: Regression tests pass
  • Verification method: All tests passing, coverage ≥90%

Technical Requirements:

  • Functionality: Comprehensive test coverage
  • Performance: Tests complete in <30 seconds
  • Security: N/A
  • Compatibility: vitest framework

Implementation Approach:

Test Organization:

commands/__tests__/
├── helpers.test.ts (15 tests)
├── install/parser.test.ts (20 tests)
├── update/parser.test.ts (15 tests)
├── kb-validate/parser.test.ts (8 tests)
├── kb-package/parser.test.ts (8 tests)
├── update-link/parser.test.ts (8 tests)
├── config-validate/parser.test.ts (8 tests)
├── dispatcher.test.ts (10 tests)
└── integration.test.ts (15+ tests)

Implementation Steps:

  1. Create test directories
  2. Create helper tests (detectSourceType, validateCommandOptions)
  3. Create parser tests for all commands (70+ tests)
  4. Create handler and dispatcher tests (20+ tests)
  5. Update config-utils tests with CommandConfig
  6. Add regression tests
  7. Run coverage report, verify ≥90%
  8. Manual testing against US KB Source Documentation & CLI Reference #90 examples

Dependencies:

Technical: None
Tasks: All previous tasks

Notes: Regression tests critical; manual testing validates against spec


T-10: Documentation and monorepo context guard validation

Priority: P0 | Estimated Hours: 1h | Bounded Context: Documentation & Validation

Summary: Add JSDoc documentation for all public types and functions, verify monorepo guard works correctly.

Type: Documentation

Description: Add comprehensive JSDoc comments with examples for all exported types and functions. Verify isInPairMonorepo() guard prevents getKnowledgeHubDatasetPath() call in release mode through tests and manual verification.

Acceptance Criteria:

  • Primary deliverable: Complete JSDoc for all public API, monorepo guard verified
  • Quality standard: All public exports documented with examples
  • Integration requirement: Documentation visible in IDE
  • Verification method: JSDoc review, manual testing

Technical Requirements:

  • Functionality: Complete documentation, accurate guard behavior
  • Performance: N/A
  • Security: N/A
  • Compatibility: JSDoc standard

Implementation Approach:

Implementation Steps:

  1. Add JSDoc to all command modules (parser.ts, handler.ts, index.ts)
  2. Add JSDoc to all helper functions
  3. Add JSDoc to dispatcher
  4. Document isInPairMonorepo() guard logic
  5. Manual testing in monorepo and release modes
  6. Update README with module structure

Dependencies:

Technical: None
Tasks: All previous tasks

Notes: Guard behavior critical for correctness in both modes


Refinement Completed By: Product Manager (AI-assisted)
Refinement Date: 2025-12-09
Review and Approval: Pending developer confirmation

Metadata

Metadata

Assignees

Labels

user storyWork item representing a user story

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions