microsoft/TypeScript
The highest-risk surfaces are process spawning and protocol trust boundaries: the binary can exec arbitrary commands for content mappers (gated by --runExternalCode) and npm installs for ATA, and the --api server exposes the host filesystem (optionally piped through client callbacks) to whoever holds the pipe/stdio. Correctness risk concentrates in the baseline corpus: thousands of accepted diffs vs the JS compiler and an explicit skip list mean behavior parity is approximate, not exact. Platform-specific code (fswatch assembly FFI, per-OS process-alive checks) and panic-prone paths (NewServer panics on missing Cwd; per-request recover in handlers) are fragile spots. Generated files and the dual go.mod workspace create mechanical traps rather than runtime risk.
- osSys.Spawn/exec.Command is a raw process-execution boundary: spawnProcess launches command[0] with args, inheriting stderr; childProcess.Close kills and reaps the child. Used for content mappers and API-side spawning.
- Content mappers execute arbitrary npm-package code declared in a project's tsconfig/package.json; execution is gated by the RunExternalCode option (--runExternalCode flag / js/ts.contentMappers.enabled setting) and NewContentMapperHost returns nil when disabled.
- ATA can shell out to `npm` (ServerOptions.NpmInstall runs exec.Command("npm", args...)); the LSP server implements ata.NpmExecutor, so a language server session can trigger package installation into the typings cache.
- The --api server binds the host filesystem directly: StdioServer wraps bundled.WrapFS(osvfs.FS()) and optionally a callbackFS delegating readFile/fileExists/directoryExists/getAccessibleEntries/realpath to the client; a named-pipe/Unix-socket transport (PipePath) is an additional local attack surface.
- Thousands of behavior diffs vs the Strada compiler are accepted wholesale in submoduleAccepted.txt, and CHANGES.md documents deliberate feature removals (Closure JSDoc, constructor expandos, several options) — parity-sensitive consumers can hit silent behavioral differences.
- The compiler-test skip list encodes known uncovered areas (all APISample_* tests and every test using removed options like verbatimModuleSyntax/importsNotUsedAsValues are skipped rather than ported).
- Platform-specific low-level code carries portability risk: fsevents_darwin_ffi_{amd64,arm64}.s hand-written assembly for FSEvents, isprocessalive_{unix,windows,other}.go for the LSP parent watchdog, and transport_{unix,windows}.go for pipes.
- Error-containment: NewServer panics when ServerOptions.Cwd is empty, and document-request handlers run under s.recover(req) so a checker crash is contained to the request; userFacingRequestFailedError distinguishes expected failures from logged errors.
- contentMapperFallbackResponse silently returns empty/null LSP responses for unknown file types during the mapper-unregistration window — a deliberate correctness-for-availability trade that can mask real errors. (inferred)
- ReuseProgram's in-place file replacement has many bail-out conditions (redirect files, importHelpers/JSX-runtime imports, supplemental file shape); subtle misses here would produce stale-program bugs that only appear in long-running sessions and are hard to baseline-test. (inferred)
- The symbol/type handle layer in the API assumes binder symbol identity is stable snapshot-wide (global atomic IDs) but assigns types per-project; cross-project symbol queries depend on a first-writer-wins canonical project that could return subtly different results depending on call order. (inferred)
- Very large generated artifacts (lsproto/lsp_generated.go from the LSP meta-model, diagnostics_generated.go from diagnosticMessages.json, ast/factory/encoder generated files in the npm package) must be regenerated via hereby generate; hand edits are overwritten and CI fails on diffs.
- Watch-mode correctness depends on debounce/coalescing in internal/fswatch (debounce.go) and watchmanager; watcher_race_test.go exists specifically because watch+rebuild had race conditions. (inferred)
- The extension warns that tsserver plugins from other extensions will not be loaded under TypeScript 7 — an ecosystem-compat gap rather than a code bug, surfaced via warnAboutTsServerPlugins.