Skip to content

SDK drift: TypeScript ServerManager's monorepo dev-path fallback for the version-mismatch check resolves to a nonexistent directory when run from compiled output #2156

Description

@realfishsam

Drift

Both ServerManager.isVersionMismatch() (TS) and _is_version_mismatch() (Python) fall back to a "monorepo dev path" to locate core/package.json when pmxt-core isn't resolvable as an installed dependency (e.g. before npm install, or in a workspace checkout). Python's relative-path traversal from __file__ correctly reaches core/package.json at the repo root. TypeScript's traversal from __dirname is written for the source directory depth and is one directory level too shallow once run from the compiled dist/ output, so existsSync(devPath) is always false there and the dev-mode version check never actually runs.

TypeScript SDK

sdks/typescript/pmxt/server-manager.ts:242-259 (isVersionMismatch):

try {
    corePackageJsonPath = require.resolve('pmxt-core/package.json');
} catch {
    // 2. Try dev path (Monorepo)
    const devPath = join(dirname(__dirname), '../../core/package.json');
    if (existsSync(devPath)) {
        corePackageJsonPath = devPath;
    }
}

This file lives at sdks/typescript/pmxt/server-manager.ts and, per tsconfig.json (outDir: "./dist", rootDir: "."), compiles to sdks/typescript/dist/pmxt/server-manager.js. Verified directory math:

  • From source (sdks/typescript/pmxt/): __dirname = sdks/typescript/pmxtdirname(__dirname) = sdks/typescript+ '../../core/package.json' = sdks/typescript/../../core/package.json = pmxt/core/package.json — correct, exists.
  • From compiled output (sdks/typescript/dist/pmxt/): __dirname = sdks/typescript/dist/pmxtdirname(__dirname) = sdks/typescript/dist+ '../../core/package.json' = sdks/typescript/dist/../../core/package.json = sdks/core/package.json — one level too shallow; this path does not exist (confirmed: /home/user/pmxt/sdks/core/package.json is absent; the real file is at /home/user/pmxt/core/package.json).

Python SDK

sdks/python/pmxt/server_manager.py:127-131:

pkg_path = Path(__file__).parent / '_server' / 'package.json'
if not pkg_path.exists():
    pkg_path = Path(__file__).parent.parent.parent.parent / 'core' / 'package.json'

Path(__file__) is sdks/python/pmxt/server_manager.py; four .parents reach the repo root regardless of whether the module is imported from source or an installed wheel (Python doesn't have a separate "compiled output" directory tier the way tsc does), so this resolves correctly in both cases: /home/user/pmxt/core/package.json (confirmed to exist).

Expected

TypeScript's devPath computation should account for the extra dist/ directory level introduced by compilation, e.g. join(dirname(dirname(__dirname)), '../../core/package.json') when built, or by deriving the path relative to the package root (e.g. via require.resolve of a known package-root marker) rather than a literal relative traversal tied to source-tree depth.

Impact

This is distinct from the already-tracked #1433, which is about the version-string comparison algorithm once both package.json files are located — this finding is about the dev-path lookup itself being unreachable from compiled output. In practice this is masked whenever require.resolve('pmxt-core/package.json') succeeds (the primary, production path) and whenever tests run directly against TS source via ts-jest (which is one directory level shallower than compiled output, so the same traversal happens to land correctly there — confirmed no test in tests/server-manager.test.ts exercises devPath directly). But any consumer running the compiled dist/ build in a monorepo/dev checkout where pmxt-core isn't a resolvable npm dependency silently loses the version-mismatch safety check that's supposed to trigger a local server restart on a stale pmxt-core binary.


Found by automated SDK cross-language drift audit

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions