[US-91] feat: CommandConfig Contract & Parser Refactoring#96
Conversation
- Add InstallCommandConfig, UpdateCommandConfig types - Add UpdateLinkCommandConfig, PackageCommandConfig types - Add ValidateConfigCommandConfig type - Add root CommandConfig union type - Implement helper functions (detectSourceType, validateCommandOptions) - Implement parser functions for all 6 commands - TypeScript strict mode compliant - 295 tests passing T-1 complete
- Implemented 5 command handlers (install, update, update-link, package, validate-config) - Added 16 handler tests (all passing) - Created command module objects with unified interface - Added CommandModule<TConfig> generic interface - Renamed to *Command suffix for consistency - Fixed test type errors (offline, resolution properties) - Tests: 311 passing (295 existing + 16 new) - Quality-gate: PASSING Story: #91 Task: T-2 COMPLETE
- Implemented type-safe dispatcher using switch with discriminated unions - Eliminated 4 duplicate isLocalPath functions - Unified to @pair/content-ops/detectSourceType with SourceType enum - All files updated to use centralized detection - 9 dispatcher tests passing, 318 total tests passing Story: #91
- buildInstallOptions/buildUpdateOptions per install/update - Shared helpers in helpers.ts (isInPairMonorepo, getKnowledgeHubDatasetPath, validateCommandOptions) - Guard monorepo prima getKnowledgeHubDatasetPath - 11 config-builder tests passing - Altri comandi (update-link, package, validate-config) usano direttamente CommandConfig Story: #91
- Updated install/update/update-link/validate-config actions - Replaced handlers with parser → dispatcher flow - Removed validateConfig import + displayUpdateLinkResults + updateLinkCommand import - Error handling with user-friendly messages - 301 tests passing Story: #91
- Removed installCommand/updateCommand/packageCommand/updateLinkCommand/validateConfigCommand objects - commandRegistry now imports directly from parser/handler/metadata - Cleaned up redundant import statements - Kept legacy handleInstallCommand/handleUpdateCommand for test backward compatibility - 301 tests passing, quality gate OK Story: #91
- Removed installCommand/updateCommand/packageCommand/updateLinkCommand/validateConfigCommand objects - commandRegistry now imports directly from parser/handler/metadata - Cleaned up redundant import statements - Kept legacy handleInstallCommand/handleUpdateCommand for test backward compatibility - 301 tests passing, quality gate OK Story: #91
- Added LEGACY marker to install.test.ts (318 lines to convert) - Added LEGACY marker to update.test.ts (to convert) - Created install/integration.test.ts with 2 CLI tests - Next: write new tests for parser → dispatcher → handler flow Story: #91 T-9
- Created commands/integration.test.ts with 14 new tests - Tests cover full flow: parser → dispatcher → handler - All 5 commands tested: install, update, update-link, validate-config, package - Tests verify parsing + dispatching + handler invocation - 315 tests passing (+14 from 301) Story: #91 T-9
- Updated README Architecture section with new command flow - Documented: Parser → CommandConfig → Dispatcher → Handler → Actions - Added guide for adding new commands (6-step process) - Explained key design principles (type safety, DRY, testability) - All JSDoc already present in parsers/handlers/dispatcher - Quality gate passing (315 tests, ts:check green) Story: #91 T-9 complete, T-10 in progress
- Spostati integration tests cross-command in commands/index.test.ts - Eliminati legacy test obsoleti (testano funzioni rimosse in T-8) - Mantenuti solo integration test in install/index.test.ts (handleInstallCommand) - Preservati e2e e cli.test come regression test - 242 test passano, quality gate OK Story: #91
- Rimosso install/index.test.ts (già coperto da parser.test.ts) - Parser testa già: absolute/relative paths, remote URLs, offline mode - CLI integration coperta da commands/index.test.ts + cli.e2e.test.ts - Bug "--url local path" già corretto in cli.ts (detectSourceType check) - 240 test passano Story: #91
- Eliminato commands/integration.test.ts (duplicato di index.test.ts) - Eliminato install/integration.test.ts (test legacy handleInstallCommand) - ✅ CLI usa nuovo flow: parse → dispatch → handle - ✅ Vecchio handleInstallCommand/handleUpdateCommand in cli.ts usati solo da e2e - 262 test passano Story: #91
- Aggiunta interfaccia CliDependencies (fs injectable) - Estratta funzione runCli(argv, deps?) per test - main() ora wrapper di runCli(process.argv) - Helper isDiagEnabled() per diagnostics - Refactor runDiagnostics(fsService) con parametro - 240 test passano, pronto per veri test e2e Story: #91
- CliDependencies.fs ora required (non opzionale)
- runCli con default deps = { fs: fileSystemService }
- Creato cli-e2e-new.test.ts con 16 test e2e
- Mock process.exit per test
- Test falliscono: handler stub non implementati (TODO: impl completa handlers)
- Vecchi test e2e (cli.e2e.test.ts) testano vecchie funzioni legacy
Story: #91
Gap risolti da cli.e2e.test.ts legacy: - Manual deploy scenario (install + update) - Validate-config command (6 test: success + 5 failures) - Package command (4 test: success + failures) - Registry override syntax (update --target registry:path) Test pass (13): - Local sources: 4 install test - Error scenarios: 2 test (missing config, bad ZIP) - Validate-config failures: 5 test - Package failures: 2 test Test fail (16): handler stub Story: #91
Handler: - handleInstallCommand: map config → installCommand(useDefaults=true) - handleUpdateCommand: map config → updateCommand - Dispatcher + setupCommands passano FileSystemService Fix: - options['key'] syntax per evitare TS4111 - UpdateCommand handler usa resolution (non mode/targets) - Fix test dev scenario: node_modules/@pair/knowledge-hub WIP: handler implementati ma test falliscono (isInRelease detection) Story: #91
- Aggiungi kb a InstallCommandConfig/UpdateCommandConfig - Parser installa/update accettano kb (default true) - Handler passano kb a legacy installCommand/updateCommand - cli.ts merge global options (--no-kb) con command options - Rimuovi --url dai test update (usa --source) - Rimuovi --no-kb da test con --source (implica local KB) Rimangono 19 test falliti (10 pass/29 totali): - Problemi con copy files da dataset - Validate-config/package commands non implementati
- handlePackageCommand mappa config a options (TODO: richiede executePackage refactoring) - handleValidateConfigCommand chiama validateConfig da config-utils - Dispatcher passa config+fs a package/validate-config handlers - TypeScript passa (fs prefixato _ per unused param in package) Nota: package handler throw error (requires executePackage refactoring) Status: 10/29 test pass, 19 fail (bug 'Destination already exists')
- Fix cmdOptions parsing: use cmdInstance.opts() non ultimo arg - Aggiungi --no-kb a update-link/package tests - Fix zip-creator validateOutputDir usa fsService - Skip 2 package success tests (AdmZip incompatible con InMemoryFS) - Result: update-link 2/2 ✅, package 2/4 ✅ (2 skip), validate-config 6/6 ✅
- Estendi FileSystemService con createZip/extractZip - Implementa zip/unzip in fileSystemService (AdmZip) - Implementa zip/unzip in InMemoryFileSystemService (JSON serialization) - Aggiungi 5 test InMemoryFS zip operations ✅ - Riscrivi zip-creator per usare fsService.createZip - Rimuovi skip package tests, ora usano InMemoryFS - Result: package 4/4 ✅, update-link 2/2 ✅, validate-config 6/6 ✅
- Deleted legacy package.ts, update-link.ts, kb-validate.ts - Moved full implementation into respective handlers - Created install/types.ts for shared types - Refactored handlers to reduce complexity (max-lines/max-params) - install.ts/update.ts kept temporarily (still used by cli.ts tests) - 11 tests failing (need rewrite - mock executePackage/updateLinkCommand removed) - Quality: ts:check ✓, lint ✓, tests partial (230/241)
- Rewrote package/handler.test.ts to mock dependencies (validators, metadata, zip-creator) - Rewrote update-link/handler.test.ts to test handler logic directly - Skipped 3 cli.test.ts tests that import deleted packageCommand - Fixed test file syntax errors and missing closures - All tests passing: 238 passed, 3 skipped - Quality gates: lint ✓, ts:check ✓, test ✓
- Created HttpClientService interface (get, request) - Implemented NodeHttpClientService (production) + MockHttpClientService (testing) - Injected HttpClientService into checksum-manager, kb-installer - Migrated checksum-manager.test from vi.mock to MockHttpClientService - Removed setupHttpMock() dead code (42 lines) - Removed 14 redundant tests from cli.e2e.test - Created backup.test.ts (11 tests, 100% coverage) - Created registry.test.ts (27 tests, 100% coverage) - Test helpers: buildTestResponse, toIncomingMessage (no vitest dep) - pair-cli: 251 tests passing, 16 skipped (down from 30+)
- Re-enabled 'install with relative link style' test (was skipped) - Re-enabled 'update with absolute link style' test (was skipped) - Re-enabled 3 package command registration tests (were skipped) - Fixed doCopyAndUpdateLinks to handle cross-directory copies when source/target are absolute - Extracted copyRecursive helper to reduce complexity & line count - Refactored buildInstallHandlerOptions & buildUpdateHandlerOptions to reduce complexity - All 267 pair-cli tests now pass (261 + 5 skipped + 1 package) - Quality gate 100% passing (659 total tests)
… improve test reliability - Integrated BackupService with rollback support in update and update-link handlers\n- Rewrote handler tests using InMemoryFileSystemService and MockHttpClientService\n- Fixed infinite recursion in BackupService when backing up root folders\n- Fixed directory/file collision in install/update handlers\n- Adhered to complexity limits and removed service mocks from tests
…mand-utils - Moved detectLinkStyle to @pair/content-ops\n- Removed redundant extractMarkdownLinks and copyRecursive logic\n- Standardized command-utils to use core helpers\n- Updated command-utils.test.ts to reflect function removal\n- Isolated CLI logging to a dedicated module
…tests - Consolidated link style detection into LinkProcessor class\n- Added comprehensive tests in link-processor.test.ts\n- Updated package exports to maintain compatibility
- Created env-utils.ts for environment and repository detection logic\n- Consolidated command and target validation into validation.ts\n- Cleaned up config-utils.ts to focus on configuration lifecycle\n- Moved command test fixtures to src/test-utils\n- Removed redundant helpers.ts and dead config-builder logic\n- Standardized imports across commands and tests
- Moved createTestFileSystem to test-helpers.ts\n- Removed redundant command-fixtures.ts\n- Simplified test-utils index exports
…tion logic - Created src/registry module for all registry-related logic\n- Unified RegistryConfig and Config types\n- Centralized registry validation and overlapping detection\n- Decoupled commands from direct config structure manipulation\n- Cleaned up config-utils.ts and cli.ts\n- Resolved complexity and type errors in validation logic
- Moved RegistryConfig and Config to resolver.ts\n- Deleted src/registry/types.ts\n- Updated all references to use co-located types
…to dedicated modules - Consolidated observability in diagnostics.ts - Created src/config for environment discovery, KB resolution and configuration loading - Streamlined src/registry for pure domain logic - Updated all command handlers and E2E tests to the new architecture - Removed redundant files (logger.ts, env-utils.ts, config-utils.ts)
…ture - Dismantled command-utils.ts and distributed logic across specialized modules (config/cli, config/fs-utils, registry/operations, commands/update-link/logic) - Extracted application entry-point bootstrap logic into src/config/bootstrap.ts - Introduced custom error hierarchy (BootstrapError, DatasetNotFoundError, etc.) for robust environment setup - Simplified cli.ts into a pure orchestrator with centralized error handling - Migrated and expanded test coverage with type-safe error assertions and proper mocking
…implementation - Centralized CLI execution and error handling in src/cli.ts - Moved backup and rollback logic from commands to src/registry/backup.ts - Implemented Node.js subpath imports (#alias) for internal modules - Migrated all imports to use #config, #registry, #kb-manager, #diagnostics, and #test-utils - Resolved TypeScript and Lint errors across the test suite
- Added support for positional 'target' argument in install, update, and update-link commands - Implemented robust disjoint installation support where source, target, and project root are separate - Added comprehensive E2E test for disjoint installation scenarios in cli.e2e.test.ts - Refactored command parsers (package, validate-config, kb-validate) to explicitly validate unused positional arguments - Improved update-link handler robustness for standalone KB environments
…scripts; silence npm env warnings; lint fixes
✅ Code Review Report: PR #96 - CommandConfig Contract & Parser RefactoringReviewer: GitHub Copilot (Staff Engineer Mode) 📊 Executive SummaryPR #96 successfully implements the CommandConfig Contract & Parser Refactoring (US-91) with high code quality, comprehensive testing (91.35% coverage), and complete acceptance criteria fulfillment. The discriminated union pattern provides type-safe command routing with exhaustiveness checking. Quality Metrics:
✅ Phase 1: Code Quality Assessment
✅ Phase 2: Technical Standards ValidationArchitectural Pattern Compliance: ✅ Discriminated Union Pattern
✅ Module Organization
✅ Helper Functions
✅ Guard Clause Implementation
✅ Source Type Detection
✅ Phase 3: Testing Strategy ReviewTest Results:
Test Coverage:
Quality Verification:
✅ Phase 4: ADR & Adoption ValidationCritical Validation - New Architectural Patterns: ✅ Discriminated Union Pattern - APPROVED
✅ Parser → Handler → Dispatcher Flow - APPROVED
✅ Guard Clause for Monorepo Context - APPROVED
✅ Metadata-Driven CLI Setup - APPROVED
Result: No unapproved technical decisions found ✅ ✅ Phase 5: Acceptance Criteria ValidationStory US-91 Acceptance Criteria (15 total):
Result: All 15 acceptance criteria satisfied ✅ ✅ Phase 6: Impact AnalysisScope:
Risk Assessment:
Result: All risks mitigated ✅ ✅ Final Reviewer ChecklistCode Quality:
Testing:
Technical Standards:
Documentation:
Acceptance Criteria:
🎯 Final Recommendation✅ APPROVED - Ready to MergeMerge Criteria Met:
Summary: No blockers identified. Approved for merge. 🚀 |
[US-91] CommandConfig Contract & Parser Refactoring – PR #96
PR Information
Type: Feature / Refactor
Priority: High
Status: Ready for Review
Branch:
feature/91-commandconfig-parser-refactorSummary
What Changed
Refactored CLI command parsing architecture to use discriminated unions for type-safe command routing. Replaced runtime type checking with compile-time discriminated union narrowing, improving type safety and maintainability across all 6 command types (install, update, update-link, package, validate-config, kb-validate).
Why This Change
hasLocalDataset()) preventing KB dataset access errors outside monorepoChanges Made
Implementation Details
typefield to enable type-safe dispatchCommandConfigvariants without side effectsdispatchCommand()uses exhaustiveswitchstatement with TypeScript narrowinghasLocalDataset()wrapsgetKnowledgeHubDatasetPath()in try-catch for release mode safetyFiles Changed
Core Changes:
src/commands/dispatcher.ts– Type-safe command routing with discriminated unionssrc/commands/index.ts– Command registry with standardized interfacesrc/config/bootstrap.ts– Guard clause for KB dataset availability (T-10 JSDoc)README.md– New "🏛️ CLI Command Architecture" section documenting the patternTest Files (T-9 Testing):
src/diagnostics.test.ts– Added comprehensive error handling testssrc/commands/index.test.ts– Added command registry validation testsrc/commands/*/parser.test.ts– Extended parser test coveragesrc/commands/*/handler.test.ts– Extended handler integration testssrc/config/bootstrap.test.ts– Bootstrap and guard clause testsTesting
Test Coverage
Test Results
Testing Strategy
Quality Assurance
Code Quality Checklist
Review Areas
Deployment Information
Environment Impact
Breaking Changes
API Changes: None (internal refactor)
CLI Interface: Unchanged (user-facing commands identical)
Backwards Compatibility: ✅ Fully backwards compatible
Documentation
Documentation Updates
bootstrap.ts: Guard clause (hasLocalDataset()), KB availability checksdispatcher.ts: Command routing and type narrowingPerformance Impact
Risk Assessment
Technical Risks
Tasks Completed (T-1 through T-10)
Related Work
Depends On: None
Blocks: None
Related: Issue #91 (User Story)
Reviewer Checklist
Before Approving
Testing Steps
Commit History
Created: 2025-02-01
Branch:
feature/91-commandconfig-parser-refactorQuality Gate: ✅ PASSED