@modernizespec/sdk
@modernizespec/sdk is the full SDK for working with ModernizeSpec files programmatically. It wraps the core types and schemas with file I/O, codebase analysis, progress tracking, and parity comparison utilities.
Installation
Section titled “Installation”npm install @modernizespec/sdkWhy an SDK
Section titled “Why an SDK”| Capability | Without SDK | With SDK |
|---|---|---|
| Read spec files | Manual JSON.parse + path resolution | ModernizeSpec.load(projectDir) |
| Validate compliance | Write your own schema validation | spec.validate() with typed errors |
| Generate from codebase | Build your own AST analysis | ModernizeSpec.analyze(projectDir) |
| Track progress | Parse migration-state.json manually | spec.state.advance("Accounts", 0.45) |
| Compare legacy vs modern | Custom diff logic | spec.parity.compare(legacy, modern) |
API Surface
Section titled “API Surface”Loading a Spec
Section titled “Loading a Spec”import { ModernizeSpec } from "@modernizespec/sdk";
// Load existing spec from projectconst spec = await ModernizeSpec.load("/path/to/project");
// Access typed dataconst domains = spec.domains; // Typed bounded contextsconst hotspots = spec.complexity; // Extraction tiers, God-classesconst plan = spec.extractionPlan; // Phased sequence with riskconst state = spec.migrationState; // Current progressValidation
Section titled “Validation”// Validate all files against schemasconst errors = spec.validate();
if (errors.length > 0) { for (const error of errors) { console.error(`${error.file}: ${error.path} — ${error.message}`); }}Codebase Analysis
Section titled “Codebase Analysis”// Generate spec from codebase analysisconst generated = await ModernizeSpec.analyze("/path/to/legacy", { language: "python", framework: "frappe",});
// Review the generated domainsconsole.log(generated.domains.contexts);Progress Updates
Section titled “Progress Updates”// Update progress for a contextstate.updateContext("Accounts", { progress: 0.45, entitiesMigrated: 12, parityTests: { passing: 68, failing: 4, total: 72 },});
// Write back to diskawait spec.save();Parity Comparison
Section titled “Parity Comparison”// Compare legacy and modern behaviorconst diff = spec.parity.compare( legacyOutput, modernOutput, { tolerance: 0.001 } // numeric precision tolerance);
console.log(diff.matches); // true if within toleranceconsole.log(diff.deviations); // list of field-level differencesKey Classes
Section titled “Key Classes”ModernizeSpec
Section titled “ModernizeSpec”The main entry point. Static methods for loading and analyzing. Instance methods for accessing, validating, and saving.
| Method | Description |
|---|---|
ModernizeSpec.load(dir) | Load spec from .agents/modernization/ |
ModernizeSpec.analyze(dir, options) | Generate spec from codebase analysis |
spec.validate() | Validate all files against schemas |
spec.save() | Write all modified files back to disk |
DomainsAccessor
Section titled “DomainsAccessor”Access bounded context data.
| Property/Method | Description |
|---|---|
spec.domains.contexts | Array of all bounded contexts |
spec.domains.contextMap | Array of context relationships |
spec.domains.getContextForFile(path) | Find which context owns a file |
spec.domains.getContext(name) | Get a specific context by name |
ComplexityAccessor
Section titled “ComplexityAccessor”Access extraction tier and hotspot data.
| Property/Method | Description |
|---|---|
spec.complexity.tiers | Array of extraction tiers |
spec.complexity.hotspots | Array of complexity hotspots |
spec.complexity.getTier(module) | Get tier for a module |
MigrationStateAccessor
Section titled “MigrationStateAccessor”Read and update progress.
| Property/Method | Description |
|---|---|
spec.migrationState.overallProgress | Overall progress (0-1) |
spec.migrationState.contexts | Per-context progress array |
spec.migrationState.blockers | Active blockers |
spec.migrationState.velocity | Velocity metrics |
spec.migrationState.updateContext(name, data) | Update context progress |
spec.migrationState.addBlocker(blocker) | Add a new blocker |
spec.migrationState.resolveBlocker(id) | Mark blocker as resolved |
Error Handling
Section titled “Error Handling”The SDK uses typed errors:
import { SpecNotFoundError, ValidationError, AnalysisError } from "@modernizespec/sdk";
try { const spec = await ModernizeSpec.load("/path/to/project");} catch (error) { if (error instanceof SpecNotFoundError) { console.error("No .agents/modernization/ directory found"); }}Next Steps
Section titled “Next Steps”- @modernizespec/cli — CLI that wraps this SDK
- @modernizespec/core — Types-only package
- MCP Server Integration — Build MCP tools with the SDK