Skip to content

feat: Implement UMS v2.0 with TypeScript support#78

Merged
synthable merged 10 commits intodevelopfrom
feat/ums-lib-v2
Oct 14, 2025
Merged

feat: Implement UMS v2.0 with TypeScript support#78
synthable merged 10 commits intodevelopfrom
feat/ums-lib-v2

Conversation

@synthable
Copy link
Copy Markdown
Owner

@synthable synthable commented Oct 13, 2025

Summary

Complete implementation of UMS v2.0 with native TypeScript support for modules and personas.

⚠️ Breaking Changes

Note: This is a v2.0 major version release with no current production users, so breaking changes are acceptable.

1. Stdin Support Removed

  • What changed: Build command no longer accepts stdin input
  • Reason: TypeScript execution requires filesystem access for import() and module resolution
  • Migration: Use --persona path/to/file.persona.ts instead of piping stdin

2. Parser API Changed

  • What changed: parseModule() and parsePersona() signatures changed
  • Before (v1.0): parseModule(yamlString: string): UMSModule
  • After (v2.0): parseModuleObject(obj: unknown): Module
  • Impact: Functions now expect JavaScript objects, not YAML strings
  • Note: The "v1.0 backward compatibility aliases" in code are misleading and will be addressed

3. v1.0 YAML Format Not Supported

  • What changed: v2.0 workflow requires TypeScript .persona.ts files
  • Reason: Enhanced type safety and native TypeScript module support
  • Impact: .persona.yml files cannot be processed by v2.0 commands

Key Changes

Core Library Updates (ums-lib)

  • v2.0 Type System: New flexible type definitions supporting both YAML and TypeScript formats
  • Adapters: TypeScript module loading with dynamic imports
  • Simplified Validation: Removed rigid schema validation in favor of flexible v2.0 structure
  • Enhanced Parsers: Support for both .module.yml/.persona.yml (v1.0) and .module.ts/.persona.ts (v2.0)
  • Updated Renderers: Markdown rendering with v2.0 metadata support

CLI Updates (copilot-instructions-cli)

  • TypeScript Loader: TSX-based loading for .module.ts and .persona.ts files
  • Enhanced Error Diagnostics: Location tracking and spec section references
  • Progress Tracking: Statistics, ETA calculation, and CI environment support
  • Build Command: Dual-format support (v1.0 YAML + v2.0 TypeScript)
  • MCP Commands: Stub implementation for future MCP server support

Migration Impact

  • ⚠️ Major version release (v2.0) with breaking changes documented above
  • ✅ All 363 tests passing (201 CLI + 162 library)
  • ✅ New TypeScript format provides enhanced type safety and developer experience

Test Coverage

  • CLI Package: 201 tests passing
  • Library Package: 162 tests passing
  • Total: 363 tests, 100% pass rate

Test Plan

  • Type checking passes across all packages
  • All unit tests pass (363/363)
  • Linting passes with no errors
  • Build succeeds for all packages
  • YAML format (v1.0) still works
  • TypeScript format (v2.0) loads correctly

Add comprehensive UMS v2.0 type definitions with full v1.0 backwards compatibility:

Core Types:
- Module interface with component-based architecture
- InstructionComponent, KnowledgeComponent, DataComponent
- ProcessStep, Constraint, Criterion directive types
- Concept, Example, Pattern knowledge types
- Enhanced metadata with capabilities, relationships, quality

Persona Types:
- Persona with spec-compliant ModuleEntry composition
- ModuleGroup for grouped module organization
- Support for both string IDs and grouped modules

Registry Types:
- RegistryEntry (renamed from ModuleEntry to avoid conflict)
- ModuleSource for provenance tracking
- ConflictStrategy types

Utilities:
- moduleIdToExportName() for kebab-case to camelCase conversion
- Transform utilities for v2.0 export naming conventions
- Enhanced error types for v2.0 operations

Backwards Compatibility:
- Deprecated v1.0 fields (meta, body, shape) preserved
- Type aliases (UMSModule, UMSPersona) maintained
- Gradual migration path for existing code

Breaking Changes: None (fully backwards compatible)

feat(parsers): add UMS v2.0 module and persona parsing

Update parsers to support v2.0 component-based architecture while maintaining v1.0 compatibility:

Module Parser:
- Support v2.0 component arrays (instruction, knowledge, data)
- Support v2.0 shorthand component properties
- Handle v2.0 capabilities field
- Maintain v1.0 shape/meta/body compatibility
- Enhanced validation for v2.0 requirements

Persona Parser:
- Support v2.0 ModuleEntry union type (string | ModuleGroup)
- Handle both grouped and ungrouped module references
- Parse v2.0 identity field (renamed from role)
- Support v2.0 domains and attribution fields
- Maintain v1.0 moduleGroups compatibility

Exports:
- Export parseModule and parsePersona for v2.0
- Maintain loadModule and loadPersona for v1.0
- Backwards compatible with existing code

Tests:
- Comprehensive v2.0 component parsing tests
- ModuleEntry union type handling tests
- Backwards compatibility test suite

refactor(validators): simplify validation for v2.0 flexibility

Streamline validators to support v2.0's flexible component architecture:

Module Validator:
- Validate v2.0 core fields (id, version, schemaVersion, capabilities, metadata)
- Support component arrays OR shorthand properties
- Validate v2.0 metadata requirements (name, description, semantic)
- Check cognitiveLevel range (0-4)
- Validate relationships and quality metadata
- Removed rigid v1.0 shape-based validation
- Maintain backwards compatibility with v1.0 modules

Persona Validator:
- Validate v2.0 persona structure
- Support ModuleEntry union type (string | ModuleGroup)
- Handle both grouped and ungrouped modules
- Check for duplicate module IDs across all groups
- Validate v2.0 metadata fields
- Removed v1.0 directive validation complexity
- Maintain backwards compatibility

Key Changes:
- Removed 600+ lines of directive-specific validation
- Simpler, more flexible validation approach
- Focus on structure over content
- Better error messages with spec references

Breaking Changes: None (validators are more permissive)

feat(core): update registry, resolvers, and renderers for v2.0

Update core library components to support v2.0 architecture:

Module Registry:
- Use RegistryEntry type (renamed to avoid conflict with ModuleEntry)
- Enhanced conflict resolution for v2.0
- Support v2.0 module composition tracking
- Improved source tracking for build reports

Module Resolver:
- Support v2.0 ModuleEntry union type (string | ModuleGroup)
- Handle both grouped and ungrouped module references
- Resolve modules from flat or grouped persona structure
- Maintain ordering from persona definition
- Enhanced duplicate detection

Markdown Renderer:
- Render v2.0 component-based modules
- Support instruction, knowledge, and data components
- Handle component arrays and shorthand properties
- Render structured directives (ProcessStep, Constraint, etc.)
- Support v2.0 attribution format
- Maintain v1.0 directive rendering compatibility

Build Report Generator:
- Generate v2.0 compliant build reports
- Include ModuleGroupReport structure
- Track composition events
- Calculate SHA-256 digests
- Support v2.0 persona structure

Tests:
- Updated for v2.0 types and structures
- Comprehensive component rendering tests
- ModuleEntry resolution tests

feat(lib): add v2.0 adapters and update library exports

Add v2.0/v1.0 interop adapters and enhance library exports:

Adapters:
- v1ToV2Adapter: Convert v1.0 modules to v2.0 format
- v2ToV1Adapter: Convert v2.0 modules to v1.0 format
- Bidirectional compatibility layer
- Preserve semantics during conversion

Library Exports:
- Export v2.0 transform utilities (moduleIdToExportName)
- Export adapter functions for interop
- Maintain all v1.0 exports
- Enhanced type exports

Benchmark Updates:
- Updated for v2.0 types
- Test both v1.0 and v2.0 code paths
- Performance comparison metrics

Breaking Changes: None (additive exports only)
Update library README to document v2.0 capabilities:

- Document v2.0 component-based architecture
- Update API examples for v2.0 types
- Add migration guide from v1.0 to v2.0
- Document new type system (Module, Persona, components)
- Update usage examples with TypeScript-first approach
- Document ModuleEntry union type for persona composition
- Add backwards compatibility notes
- Update installation and getting started sections
Phase 5.1 - Implement on-the-fly TypeScript execution for .module.ts and .persona.ts files without pre-compilation.

- Add tsx@^4.20.6 dependency for TypeScript execution
- Create typescript-loader.ts with loadTypeScriptModule() and loadTypeScriptPersona()
- Add version detection utilities (detectUMSVersion, isTypeScriptUMSFile, isYAMLUMSFile)
- Validate module IDs match between file and export name
- Support default exports and named exports for personas
- Add comprehensive test coverage for loader utilities

This enables v2.0 TypeScript-first module format while maintaining v1.0 YAML support.

feat(cli): add v2.0 TypeScript format support to build command

Phase 5.1 - Update build pipeline to handle both v1.0 (YAML) and v2.0 (TypeScript) formats.

**Module Discovery (module-discovery.ts)**:
- Add loadModuleFile() helper to detect and load both .module.yml and .module.ts formats
- Update discoverStandardModules() to handle both formats automatically
- Update discoverLocalModules() to use the new loadModuleFile helper
- Use detectUMSVersion() and loadTypeScriptModule() for v2.0 files

**File Operations (file-operations.ts)**:
- Update discoverModuleFiles() to search for both .module.yml and .module.ts files
- Update isPersonaFile() to accept both .persona.yml and .persona.ts extensions
- Update validatePersonaFile() error messages for dual format support

**Build Command (build.ts)**:
- Add loadTypeScriptPersona import and detectUMSVersion for format detection
- Update setupBuildEnvironment() to detect persona format and load accordingly:
  - v1.0: Parse YAML with parsePersona()
  - v2.0: Load TypeScript with loadTypeScriptPersona()
- Update processPersonaAndModules() to handle both formats:
  - v2.0: Extract IDs from modules array (ModuleEntry union type)
  - v1.0: Extract IDs from moduleGroups array
- Update verbose logging to count groups in both formats
- Update progress messages to indicate detected UMS version

This enables seamless building of both v1.0 and v2.0 personas while maintaining full backwards compatibility.

feat(errors): enhance error diagnostics with location and spec references

Task 5.2 - Improve error handling and diagnostics for better developer experience.

**ums-lib error types (errors.ts)**:
- Add ErrorLocation interface with filePath, line, column fields
- Extend UMSError base class with location and specSection properties
- Update all error constructors to accept location and specSection:
  - UMSValidationError: Add location and specSection parameters
  - ModuleLoadError: Add location and specSection with auto-location from filePath
  - PersonaLoadError: Add location and specSection with auto-location from filePath
  - BuildError: Add location and specSection parameters

**CLI error handler (error-handler.ts)**:
- Add formatLocation() helper to format error locations as "path:line:column"
- Add formatSpecSection() helper to display spec references in cyan
- Enhance handleValidationError():
  - Display location with line/column information
  - Show spec section references for validation errors
  - Use emoji (❌) for better visual clarity
- Enhance handleLoadError():
  - Display location information for load errors
  - Add spec section references
  - Update suggestions for TypeScript support (export names)
- Enhance generic UMS error handler:
  - Display location and spec section for all UMS errors
  - Improved formatting consistency

**Error Format Example**:
```
❌ Error: Invalid module ID format

   Location: src/modules/error-handling.module.ts:line 3, column 5
   Field: id
   Specification: Section 2.1 (Module ID Format)

  Suggestions:
    • Check YAML/TypeScript syntax and structure
    • Verify all required fields are present
    • Review UMS specification for correct format
```

This enables precise error reporting with file locations and actionable guidance linked to specification sections.

feat(progress): enhance progress tracking with statistics and CI support

Task 5.3 - Improve progress indicators for better UX and CI compatibility.

**Progress enhancements (progress.ts)**:
- Add isCI() helper to detect CI environments (CI, CONTINUOUS_INTEGRATION, BUILD_NUMBER, RUN_ID)
- Enhance BatchProgress with statistics tracking:
  - ETA calculation based on processing rate
  - Percentage completion display
  - Throughput metrics (items/second)
  - Duration tracking
- Add CI-specific logging:
  - Log progress milestones every 10% in CI environments
  - Always log in CI mode for better build logs
  - Timestamps for all CI output
- Add helper functions for common batch operations:
  - createModuleLoadProgress() for module loading operations
  - createModuleResolveProgress() for module resolution

**Progress output example**:
```
⠹ loading modules (42/100) 42% - module/error-handling ETA: 3s
✔ Processed 100 items in 5.2s (19.2 items/s)
```

**CI output example**:
```
[2025-10-12T10:30:00.000Z] [INFO] build:loading modules - Starting (total: 100)
[2025-10-12T10:30:01.000Z] [INFO] Progress: (10/100) 10% complete
[2025-10-12T10:30:02.000Z] [INFO] Progress: (20/100) 20% complete
...
[2025-10-12T10:30:05.000Z] [INFO] build:loading modules - Processed 100 items in 5.2s (19.2 items/s)
```

This provides clear feedback in both interactive terminals and CI/CD pipelines.
Remove all UMS v1.0 backward compatibility code and update tests for v2.0 only.

Breaking Changes:
- ums-lib: Remove v1.0 directive/shape/meta validation
- ums-lib: Remove v1.0 moduleGroups from persona format
- CLI: Remove v1.0 type imports (UMSModule)
- CLI: Remove shape display from inspect command
- CLI: Update test expectations for v2.0 module format
- CLI: Add loadTypeScriptPersona mock for build tests

Test Coverage:
- ums-lib: All 162 tests passing
- CLI: All 201 tests passing
- Total: 363/363 tests passing

Technical Details:
- Use ComponentType enum for type-safe component discrimination
- Add ESLint rule exceptions for runtime validation checks
- Fix nullish coalescing for optional properties
- Use forEach for iteration without unused variables
- Fix ums-mcp ESLint errors (nullish coalescing, catch types)

Files Changed:
- ums-lib: Enhanced module-validator with v2.0 rules
- ums-lib: Rewrote module-parser and persona-parser tests
- ums-lib: Updated markdown renderer with proper enum usage
- CLI: Fixed build tests to mock loadTypeScriptPersona
- CLI: Updated module-discovery tests for new standard path
- CLI: Removed v1.0 fallbacks from type extensions
- ums-mcp: Fixed ESLint errors for type safety
Apply consistent code formatting across CLI and library packages
following project Prettier configuration and ESLint rules.

Changes:
- Apply prettier formatting (line wrapping, indentation)
- Fix nullish coalescing operator usage in isCI()
- Remove unused variable in error handler
- Remove unnecessary type annotation
Copilot AI review requested due to automatic review settings October 13, 2025 05:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements UMS v2.0 with native TypeScript support for modules and personas, building on the existing v1.0 YAML infrastructure. The core enhancement introduces TypeScript module loading via TSX, modernized type definitions, and updated renderers while maintaining complete backwards compatibility.

Key changes:

  • TypeScript Support: New .module.ts and .persona.ts format support with dynamic loading
  • Enhanced Type System: Complete v2.0 type definitions supporting flexible component structures
  • Improved CLI Experience: Enhanced progress tracking, ETA calculation, and better error diagnostics

Reviewed Changes

Copilot reviewed 46 out of 47 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
vitest.config.ts Adds coverage exclusions for test utilities and CLI entry points
packages/ums-mcp/src/index.ts New MCP server entry point for Claude Desktop integration
packages/ums-lib/src/utils/transforms.ts Module ID to TypeScript export name transformation utilities
packages/ums-lib/src/utils/errors.ts Enhanced error types with location tracking and spec references
packages/ums-lib/src/types/index.ts Complete v2.0 type system with component-based architecture
packages/ums-lib/src/core/validation/*.ts Updated validators for v2.0 specification compliance
packages/ums-lib/src/core/rendering/*.ts Modernized renderers supporting v2.0 component structure
packages/copilot-instructions-cli/src/utils/typescript-loader.ts TSX-based TypeScript module and persona loading
packages/copilot-instructions-cli/src/utils/progress.ts Enhanced progress tracking with ETA and CI environment support
Comments suppressed due to low confidence (1)

packages/copilot-instructions-cli/src/commands/build.ts:1

  • The comment specifies 'Path to persona .ts file' but the implementation still supports both .ts and .yml files through the loader. The documentation should reflect the actual supported formats or the implementation should be constrained to match the documentation.
/**

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +26 to +40
export function moduleIdToExportName(moduleId: string): string {
// Get the final segment after the last '/'.
// If no '/', the whole string is the final segment.
const finalSegment = moduleId.includes('/')
? moduleId.substring(moduleId.lastIndexOf('/') + 1)
: moduleId;

// Transform kebab-case to camelCase.
return finalSegment
.split('-')
.map((part, index) =>
index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
)
.join('');
}
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function doesn't handle empty string inputs properly. If moduleId is an empty string, finalSegment will be empty, and split('-') will return [''], resulting in an empty string output which may not be the intended behavior for export names.

Copilot uses AI. Check for mistakes.
Comment on lines +147 to +155
export function detectUMSVersion(filePath: string): '1.0' | '2.0' {
if (filePath.endsWith('.module.ts') || filePath.endsWith('.persona.ts')) {
return '2.0';
}
if (filePath.endsWith('.module.yml') || filePath.endsWith('.persona.yml')) {
return '1.0';
}
throw new Error(`Unknown UMS file format: ${filePath}`);
}
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting the file extension patterns to constants to avoid duplication and make maintenance easier. The same patterns are used in isTypeScriptUMSFile and isYAMLUMSFile functions.

Copilot uses AI. Check for mistakes.
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @synthable, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a major upgrade to the Unified Module System (UMS) by implementing version 2.0 of its specification. The core focus is on integrating native TypeScript support, enabling developers to define modules and personas directly using TypeScript files for improved type safety and a better development experience. Concurrently, the CLI tooling has been significantly enhanced with more precise error reporting and detailed progress tracking, streamlining the management of UMS artifacts. Crucially, these changes maintain full backwards compatibility with existing v1.0 YAML files, ensuring a seamless migration path for all users.

Highlights

  • UMS v2.0 Core Implementation: The Unified Module System (UMS) library has been completely overhauled to support version 2.0 of its specification, introducing a more flexible and robust structure for modules and personas.
  • Native TypeScript Support: Modules and personas can now be defined directly in TypeScript files (.module.ts, .persona.ts), leveraging tsx for dynamic loading, which significantly enhances type safety and developer experience.
  • Enhanced CLI Functionality: The copilot-instructions-cli has been updated to fully support UMS v2.0 TypeScript files, featuring improved error diagnostics with location tracking and spec section references, as well as advanced progress indicators including ETA calculation and CI environment awareness.
  • New Module and Persona Structure: A flexible component-based system for modules (supporting instruction, knowledge, and data components) and a streamlined persona definition with explicit module entries and grouping have been introduced.
  • Backwards Compatibility: All existing UMS v1.0 YAML files (.module.yml, .persona.yml) remain fully functional and supported, ensuring a smooth transition for current users without breaking changes.
  • MCP Server Stub: Initial implementation of commands for a future MCP (Module Control Protocol) server has been added, including start, test, validate-config, and list-tools.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant and impressive undertaking, migrating the UMS system to v2.0 with native TypeScript support. The new type system and component-based module structure are well-designed and offer much more flexibility. The changes to the CLI to support TypeScript loading, improve progress tracking, and enhance error diagnostics are also valuable additions.

However, the review has identified several critical issues and breaking changes that need to be addressed:

  • Breaking Changes: The PR description claims zero breaking changes, but support for stdin in the build command has been removed, and automatic discovery of standard modules is now disabled. These are significant changes to the CLI's behavior.
  • API Breakage in ums-lib: The parseModule and parsePersona functions have had their signatures changed, which is a breaking change for the library's API and has introduced critical bugs in the CLI itself, breaking v1.0 YAML file processing.
  • Regressions: The new module validator for v2.0 is less comprehensive than the v1.0 validator, as it no longer validates the content of components.
  • Bugs: A minor bug was found in the build report generation where the schema version is hardcoded.

Addressing these issues will ensure the stability and backward compatibility of the system, aligning the implementation with the goals stated in the pull request description.

Address all 4 issues identified in PR #78 review:

1. Add input validation for empty strings in moduleIdToExportName()
   - Throw descriptive errors for empty/whitespace-only module IDs
   - Add validation for malformed IDs with trailing slashes
   - Update tests to verify error handling

2. Improve ESLint suppression comment in persona-validator
   - Add detailed explanation of why runtime validation is necessary
   - Clarify that TypeScript types don't protect against external data

3. Extract file extension constants in typescript-loader
   - Define FILE_EXTENSIONS constant to eliminate duplication
   - Update all file extension checks to use constants
   - Improves maintainability and reduces typo risk

4. Remove commented code in module-discovery
   - Delete 10-line commented code block
   - Preserve decision rationale in JSDoc comment
   - Improves code readability

All tests passing (365/365). No functional changes to existing behavior.
@synthable synthable requested a review from Copilot October 13, 2025 09:54
@synthable
Copy link
Copy Markdown
Owner Author

/gemini review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 46 out of 47 changed files in this pull request and generated 7 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +44 to +49
return finalSegment
.split('-')
.map((part, index) =>
index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
)
.join('');
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider extracting the camelCase transformation logic into a separate utility function for reusability, as this pattern may be needed elsewhere.

Copilot uses AI. Check for mistakes.
Comment on lines +296 to +299
export type Component =
| InstructionComponent
| KnowledgeComponent
| DataComponent;
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The union type lacks a JSDoc comment explaining the discriminated union pattern and how to use the type field for type narrowing.

Copilot uses AI. Check for mistakes.
// Handle ModuleGroup object
// Runtime validation required: persona data comes from external files (YAML/JSON)
// which may not conform to TypeScript types. TypeScript provides compile-time safety
// only - we must validate at runtime to catch malformed input data.
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The runtime validation approach is correct for external data, but consider documenting this pattern more broadly as it's used throughout the codebase.

Suggested change
// only - we must validate at runtime to catch malformed input data.
// only - we must validate at runtime to catch malformed input data.
//
// [Pattern Documentation] This runtime validation pattern is used throughout the codebase
// whenever handling external data (e.g., YAML/JSON input). TypeScript types do not provide
// runtime guarantees, so we must explicitly check types and structure at runtime to ensure
// data integrity and prevent runtime errors. Please refer to this pattern when adding new
// validation logic for external data elsewhere in the codebase.

Copilot uses AI. Check for mistakes.
typeof value === 'object' &&
value !== null &&
'id' in value &&
typeof value.id === 'string'
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The type guard only validates the 'id' property but trusts TypeScript exports. Consider adding validation for other essential properties like 'schemaVersion' to catch malformed exports earlier.

Suggested change
typeof value.id === 'string'
typeof value.id === 'string' &&
'schemaVersion' in value &&
(typeof (value as any).schemaVersion === 'string' || typeof (value as any).schemaVersion === 'number')

Copilot uses AI. Check for mistakes.
Comment on lines +175 to +178
const rate = this.current / elapsed; // items per ms
const remaining = this.total - this.current;
const eta = remaining / rate; // ms remaining
const etaSeconds = Math.round(eta / 1000);
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Division by zero can occur when elapsed time is 0 (very fast operations). This will result in Infinity or NaN values for rate and eta.

Suggested change
const rate = this.current / elapsed; // items per ms
const remaining = this.total - this.current;
const eta = remaining / rate; // ms remaining
const etaSeconds = Math.round(eta / 1000);
const remaining = this.total - this.current;
let rate: number;
let eta: number;
let etaSeconds: number;
if (elapsed > 0) {
rate = this.current / elapsed; // items per ms
eta = rate > 0 ? remaining / rate : Infinity; // ms remaining
etaSeconds = Math.round(eta / 1000);
} else {
rate = 0;
eta = Infinity;
etaSeconds = 0;
}

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +28
/** Path to persona .ts file */
persona: string;
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The breaking change from optional to required persona parameter should be documented in migration notes, as this affects existing CLI usage patterns.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and impressive migration to UMS v2.0 with native TypeScript support. The new type system, TS-native module definitions, and enhanced CLI features like progress tracking and error diagnostics are excellent improvements. However, my review has identified several critical issues concerning backward compatibility with v1.0 YAML files. The PR description states full backward compatibility, but the parsing and validation logic for v1.0 appears to be broken or missing, which impacts several CLI commands. Additionally, there are some undocumented breaking changes to the ums-lib API and CLI behavior. My feedback focuses on these critical compatibility problems, along with some medium-severity suggestions to enhance robustness and code clarity.

Comment on lines +114 to +130
// Try to find the persona export
// Common patterns: default export, or named export matching filename
let personaObject: Persona | undefined;

// Check for default export
const defaultExport = personaExports.default;
if (isPersonaLike(defaultExport)) {
personaObject = defaultExport;
} else {
// Try to find any Persona-like object in exports
const exports = Object.values(personaExports);
const personaCandidate = exports.find(isPersonaLike);

if (personaCandidate) {
personaObject = personaCandidate;
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for discovering the exported Persona object is not very strict. It first checks for a default export, and if that's not a valid persona, it scans all other named exports. This could lead to ambiguous behavior if a persona file happens to export multiple objects that match the isPersonaLike type guard.

To make this loader more robust and predictable, consider enforcing a single, clear convention for exporting personas, such as requiring a default export. This would simplify the loading logic and provide a clearer contract for users creating .persona.ts files.

…eports

Issue identified by Gemini Code Assist review of PR #78.

Before: Build reports always claimed schemaVersion: '1.0'
After: Build reports correctly reflect the persona's actual schema version

Impact: Build reports for v2.0 personas will now correctly show schemaVersion: '2.0'

Test coverage: All 164 tests passing in ums-lib
The v2.0 migration in commit eb75803 did not update the UMS_SCHEMA_VERSION
constant or domain export comments, leaving v1.0 references throughout
the codebase despite all types, validators, and parsers being v2.0.

Changes:
- Update UMS_SCHEMA_VERSION constant from '1.0' to '2.0'
- Update parsing domain export comments to reference v2.0
- Update validation domain export comments to reference v2.0
- Update resolution domain export comments to reference v2.0
- Update registry domain export comments to reference v2.0
- Update core domain export comments to reference v2.0
- Update utils export comments to reference v2.0
- Update main library export comments to reference v2.0
- Update YAML utilities comment to reference v2.0

This completes the v2.0 migration by ensuring all constants and
documentation correctly reference v2.0 instead of v1.0.

Impact: Library now consistently identifies itself as v2.0 throughout.
…issues

Remove all v1.0 YAML file support from CLI and ums-lib, transitioning
fully to v2.0 TypeScript-only format. Address critical and high-priority
issues identified in PR #78 review comments.

**Breaking Changes:**
- v1.0 YAML files (.module.yml, .persona.yml) are no longer supported
- validate command now returns message that validation is not implemented
  for v2.0 (TypeScript provides compile-time type checking)
- parseModule and parsePersona exports removed from ums-lib

**Fixes:**
- Remove misleading "backward compatibility aliases" comment (parseModule/parsePersona)
- Fix unsafe type casting in inspect.ts by adding isCLIModule() type guard
- Fix division by zero bug in progress.ts ETA calculation
- Remove broken v1.0 YAML validation logic from validate command
- Remove v1.0 YAML module loading from module-discovery
- Remove v1.0 YAML support from file-operations (discoveryModuleFiles, isPersonaFile, validatePersonaFile)
- Remove v1.0 YAML detection functions from typescript-loader (detectUMSVersion, isYAMLUMSFile)

**Test Updates:**
- Update all test files to reflect v2.0 TypeScript-only support
- Remove obsolete validate.test.ts (validate command is now a stub)
- Fix test expectations for new error messages and behavior

All tests passing: CLI (184/184), ums-lib (164/164)

Addresses review comments from PR #78
Remove obsolete v1.0 agents and documentation:
- Delete .claude/agents/ums-module-evaluator.md (v1.0)
- Delete .claude/agents/ums-persona-evaluator.md (v1.0)
- Delete docs/USER_GUIDE.md (v1.0)
- Delete docs/processes/ums-module-evaluation-process.md (v1.0)
- Delete docs/processes/ums-persona-evaluation-process.md (v1.0)

Update documentation for v2.0:
- Update README.md with TypeScript examples and v2.0 features
- Update docs/README.md to reflect new documentation structure
- Update packages/ums-lib/README.md with v2.0 API documentation
- Update packages/ums-lib/package.json description for v2.0

All documentation now reflects the TypeScript-first approach and v2.0
module/persona format with full type safety.
@synthable
Copy link
Copy Markdown
Owner Author

@copilot-pull-request-reviewer Please review the latest changes

@gemini-code-assist Please review the latest changes

Latest commit includes:

  • docs(v2.0): remove v1.0 documentation and update README files for v2.0

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an impressive and extensive pull request that successfully implements the transition to UMS v2.0 with first-class TypeScript support. The breaking changes are well-documented, and the new architecture with a platform-agnostic ums-lib and a TypeScript-aware CLI is a significant improvement. The enhanced error handling and progress indicators in the CLI will greatly improve the developer experience.

I've identified a few areas for improvement, mainly related to cleaning up some leftover code from v1.0 and updating the library's documentation to reflect the new API. I also suggest renaming a couple of test files for better clarity. Overall, this is a very solid piece of work.

@@ -1,15 +1,17 @@
import { describe, it, expect } from 'vitest';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test file seems to be testing the functionality of validateModule from module-validator.ts, but its name is module-parser.test.ts. To improve clarity and maintainability, consider renaming this file to module-validator.test.ts to accurately reflect its contents.

@@ -1,303 +1,441 @@
import { describe, it, expect } from 'vitest';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the module test file, this file is named persona-parser.test.ts but it's testing validatePersona from persona-validator.ts. For better project structure and clarity, it would be beneficial to rename this file to persona-validator.test.ts.

@synthable synthable merged commit 1c7fec8 into develop Oct 14, 2025
@synthable synthable deleted the feat/ums-lib-v2 branch October 14, 2025 10:11
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.

2 participants