Skip to content

feat(cli): capture Effect and TypeScript versions in audit context #21

@aridyckovsky

Description

@aridyckovsky

Motivation

When auditing a project's migration state, knowing which versions of Effect and TypeScript are in use helps AI agents provide appropriate migration advice and track progress from source → target versions.

Proposed Solution

Add an optional versions block to audit.json that captures dependency versions from the audited project.

Schema Design

export const VersionPair = Schema.Struct({
  declared: Schema.optional(Schema.String),  // from package.json
  installed: Schema.optional(Schema.String)  // from node_modules
})

export const DependencyVersions = Schema.Struct({
  effect: Schema.optional(VersionPair),
  typescript: Schema.optional(VersionPair),
  effectFamily: Schema.optional(Schema.Record({
    key: Schema.String, 
    value: VersionPair
  })),  // @effect/io, @effect/data, etc.
  node: Schema.optional(Schema.String),
  packageManager: Schema.optional(Schema.Struct({
    name: Schema.String,
    version: Schema.optional(Schema.String)
  })),
  errors: Schema.optional(Schema.Array(Schema.String))
})

// Extend AmpAuditContext
export const AmpAuditContext = Schema.Struct({
  // ... existing fields
  versions: Schema.optional(DependencyVersions)
})

Detection Strategy

  1. Read package.json (declared versions from dependencies/devDependencies/peerDependencies)
  2. Read node_modules/<pkg>/package.json (installed versions)
  3. Detect package manager:
    • Prefer package.json.packageManager field
    • Fallback to lockfile detection (pnpm-lock.yaml, yarn.lock, etc.)
  4. Capture Node version from process.versions.node

Packages to Track

Core:

  • effect
  • typescript

Legacy Effect family:

  • @effect/io, @effect/data, @effect/schema, @effect/platform, @effect/platform-node

Useful TS ecosystem:

  • @types/node
  • ts-node

Error Handling

  • Best-effort detection (don't fail audit if versions can't be detected)
  • Collect diagnostic messages in versions.errors array
  • Return undefined values for missing packages

Example Output

{
  "version": 1,
  "toolVersion": "0.1.0",
  "timestamp": "2025-11-05T16:00:00.000Z",
  "versions": {
    "effect": {
      "declared": "^3.18.4",
      "installed": "3.18.4"
    },
    "typescript": {
      "declared": "^5.9.3",
      "installed": "5.9.3"
    },
    "effectFamily": {
      "@effect/platform": {
        "declared": "^0.92.1",
        "installed": "0.92.1"
      },
      "@types/node": {
        "declared": "^24.10.0",
        "installed": "24.10.0"
      }
    },
    "node": "22.11.0",
    "packageManager": {
      "name": "pnpm",
      "version": "10.14.0"
    }
  },
  "findings": { /* ... */ }
}

Implementation Steps

  1. Add VersionPair and DependencyVersions schemas to context-writer.ts
  2. Extend AmpAuditContext with optional versions field
  3. Implement detectVersions Effect that reads package.json and node_modules
  4. Call detectVersions in writeAmpContext and include in output
  5. Add unit tests covering:
    • Successful detection
    • Missing package.json
    • Missing node_modules
    • Error collection

Backward Compatibility

  • versions field is optional (no breaking change)
  • ✅ Existing audit.json consumers can ignore the field
  • ✅ Audit doesn't fail if version detection fails

Future Enhancements

  • Migration targets: Capture target versions from config (e.g., "migrate to Effect 3.x")
  • Workspace support: Resolve exact versions from lockfiles for monorepos
  • Broader ecosystem: Track eslint, bundlers, etc.

Estimated Effort

Medium (1-3 hours including tests)

Metadata

Metadata

Assignees

No one assigned

    Labels

    amp:auditAudit context and structured violation outputpkg:cliIssues related to @effect-migrate/cli packageschemaSchema validation and typestype:featureNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions