Codex TypeScript semantic reads
Codex TypeScript semantic reads
From CLI 6.1.0, the TypeScript Pack gives Codex native TypeScript 7 semantic reads through Typegraph MCP. hi update installs one pinned Tool Runtime per machine, finds the repository's Compiler Projects, checks that each one loads, and registers one read-only Codex server per passing project in .codex/config.toml. hi check reports the result. No other setting is needed. The spec, architecture, and implementation notes hold the decisions and acceptance evidence.
Semantic reads never replace format, lint, or typecheck evidence. Existing TypeScript/Effect hooks and the lint and typecheck commands remain the validation gates.
Requirements
- The
typescriptPack in settingspacks. It depends on thetypegraph-runtimeRegistry Item, so selecting the Pack is the only switch. - CLI 6.1.0 or newer. Older CLIs ignore the Tool Runtime and register nothing.
- Node 22.18 or newer and
npmon thePATHthathiruns with. shandgiton thePATHCodex runs with. Windows needs ashonPATH; no per-platform matrix is tested.- Codex must trust the project. Codex loads a project
.codex/config.tomlonly for trusted projects.
What hi update does
The semantic-reads step runs after the Installed Record is written and before managed lint. hi init runs the same step.
Tool Runtime
The Registry Item carries the exact package.json and package-lock.json text (Typegraph 0.9.56, TypeScript 7.0.2, @effect/tsgo 0.36.5, MCP SDK 1.30.1). The runtime lives outside every repository at:
${XDG_DATA_HOME:-~/.local/share}/hi-tools/typegraph-mcp/<version>- A receipt
.hi-runtime.jsonrecords the SHA-256 of the lockfile at install time. The Registry stores no digest. - When the receipt matches the pinned lock and the server entry exists, the runtime is
reusedwith no process and no write. - Otherwise
hi updatewrites the manifest and lock to a sibling staging directory, runsnpm ci --ignore-scripts --no-audit --no-fundthere, writes the receipt, and swaps the directory into place. The report saysinstalled. - A Node older than 22.18, a missing
npm, or a failed install makes the runtimeunavailablewith a reason. No Codex entry is written, HI's block is removed, and the update status staysapplied. - The runtime is never pruned, including after the Pack is deselected or a newer version is pinned. Remove old
hi-tools/typegraph-mcp/<version>directories by hand when no repository uses them. - Project manifests, lockfiles, and tsconfigs are only read.
Compiler Project discovery
A Compiler Project is the program one tsconfig.json selects.
- Candidates are files named
tsconfig.jsonfromgit ls-files --cached --others --exclude-standard, so git-ignored configs never count. Outside git, a depth-bounded walk skipsnode_modules,dist, and dot-directories. - The Recorded Shape wiki root is excluded (
wiki). - A solution-only config (
files: []with noinclude) is excluded (solution-only). In this repository, that is the roottsconfig.json. - When one candidate's directory contains another's, both are
ambiguous: they are reported and get no entry. - Settings
typescript.compilerProjectsreplaces discovery with the listed tsconfig paths. Use it to resolve ambiguity or to pick projects by hand. Paths must stay inside the repository; a missing path is reported asoverride not found.
{
"typescript": { "compilerProjects": ["apps/cli/tsconfig.json", "packages/contract/tsconfig.json"] }
}Load probe
Each discovered project is loaded once through Typegraph's compiler API. It passes only when the project has at least one source file. A project that fails, for example with 0 source files, gets no Codex entry and is reported with its reason. Probes run four at a time, each bounded to 60 s, and no process outlives the step. A project's declared TypeScript version does not matter: "compatible" means the bundled TypeScript 7.0.2 loads it.
Codex entries
HI owns one fenced block in the Authored .codex/config.toml:
# BEGIN hi typegraph (generated by hi update; edits are restored)
[mcp_servers.typegraph_apps_cli]
command = "sh"
args = ["-c", 'TYPEGRAPH_PROJECT_ROOT="$(git rev-parse --show-toplevel)" exec node "${XDG_DATA_HOME:-$HOME/.local/share}/hi-tools/typegraph-mcp/0.9.56/node_modules/typegraph-mcp/dist/server.cjs"']
env = { TYPEGRAPH_TSCONFIG = "apps/cli/tsconfig.json" }
enabled_tools = ["ts_find_symbol", "ts_definition", "ts_references", "ts_type_info", "ts_module_exports"]
default_tools_approval_mode = "approve"
startup_timeout_sec = 20
tool_timeout_sec = 60
# END hi typegraph- One
[mcp_servers.typegraph_<slug>]table per probe-passing project. The slug is the tsconfig directory with other characters mapped to_; a root project istypegraph_root. - The launch command resolves the Git worktree root from Codex's working directory and the runtime from
XDG_DATA_HOMEorHOME. The committed file holds no absolute home path, and each worktree gets answers from its own files. - Every byte outside the block is left as it is. A missing block is appended after one blank line.
- Each
hi updaterestores the block: hand edits inside it are overwritten. Put custom settings outside the block. - With the Pack deselected, or no passing project, the block is removed and the rest of the file is untouched. The runtime stays installed.
- A table with the same name defined outside the block wins. HI skips its own table and reports
typegraph_<slug> is already defined outside the hi typegraph block. - Malformed or duplicated block markers leave the file untouched and are reported. Fix or delete the markers, then run
hi updateagain. - HI writes no top-level
approval_policyand never touches~/.codex.
The update report prints one semantic-reads line, for example Semantic reads: Typegraph runtime reused at <path>; load probe passes for 10 of 10 Compiler Projects; .codex/config.toml unchanged., followed by one line per failed or ambiguous project and per conflict. hi update --json carries the same facts under semanticReads (runtime, projects, excluded, codexConfig, conflicts).
With the Pack selected, the Built .devpunks/AGENT-HANDOFF.md adds a "TypeScript semantic reads in Codex" section: the server naming, the five reads, the new-session rule, and that reads never replace format, lint, or typecheck evidence.
The five reads
ts_find_symbol: locate a named symbol in a file.ts_definition: resolve the declaration behind a symbol or import.ts_references: return semantic references. The result can include the declaration withisDefinition: false; do not treat the raw count as an exact impact count.ts_type_info: return the inferred type and documentation.ts_module_exports: list a module's exported symbols.
Use the server whose TYPEGRAPH_TSCONFIG owns the queried file. Imported sources may belong to that program too, but an unrelated project is not visible. File arguments are repository-relative, such as apps/cli/src/index.ts. Typegraph's LSP hover, graph, and Effect diagnostic tools stay disabled: hover kept a stale type after a dependency edit in testing.
Check health
hi check adds semantic reads only when the Installed Record lists typegraph-runtime. It reads the pinned runtime from the installed Baseline's item (download cache first), the servers in HI's block, and one load probe per Compiler Project. These are three separate facts, and none of them changes status:
Typegraph runtime: installed 0.9.56 (/home/me/.local/share/hi-tools/typegraph-mcp/0.9.56)
Codex entries: 10 registered
Compiler projects: 10 pass, 0 fail- A missing runtime prints
Typegraph runtime: not installed: <reason>, for exampletypegraph-mcp 0.9.56 is not installed at <path>orwas installed from a different lockfile. Its projects are reported asnot probed: Tool Runtime not installed. Runhi update. Codex entries: 0 registeredwith an installed runtime means the block is absent or was edited away. Runhi update.- Each failed or ambiguous project prints its own indented line with the reason.
- Probes are bounded to 10 s each and 30 s together, so the session-start hook stays under its 45 s timeout. Past the budget, every project reports
not probed: hi check probe budget (30 s) spent. hi check --jsonaddssemanticReads.runtime(installed,version,path,reason),semanticReads.registered(count,servers), andsemanticReads.compilerProjects[](tsconfig,server,probe:pass,failorambiguous,registered,reason).
Registration is not a successful read. To prove a session end to end, start a new Codex session in the checkout and ask for:
typegraph_apps_cli.ts_definitionwithfile: "apps/cli/src/index.ts",symbol: "commandRegistry". Expectapps/cli/src/cli/command-registry.ts.typegraph_packages_contract.ts_type_infowithfile: "packages/contract/src/reports.ts",symbol: "HarnessReportType". Expect"bug" | "docs" | "other" | "tooling" | "workflow".
codex mcp get typegraph_apps_cli --json shows the registered entry and its five enabled_tools.
Limitations
- New session after config changes. Answers follow source edits on disk. After a tsconfig, dependency, or branch change, start a new Codex session. A running session is not restarted for you.
- Desktop approval is unverified. The entries set
default_tools_approval_mode = "approve".codex exec(codex-cli 0.156.1) ran every read without a prompt. The interactive desktop app was not observed. If it prompts for or refuses a Typegraph read, report it withhi report. HI changes no approval policy. - Trusted project only. An untrusted project ignores
.codex/config.toml, so no Typegraph server starts. - Shell and Node. The launch needs
sh,git, and Node 22.18 or newer on Codex'sPATH. A startup "module not found" error means the runtime is missing on this machine; runhi update. Failure to resolve a Git root means Codex was started outside the checkout. - Wrong server.
source file not foundusually means the query went to a server whose program does not own the file.
Session cost
Measured on Linux x86_64 with this repository's 10 Compiler Projects (codex-cli 0.156.1, Node 24.19.0). No threshold applies.
- 10 servers expose 50 tools (5 reads each). Each server advertises 22 tools before
enabled_toolsfilters them. - Each server was ready in 493–745 ms with all 10 starting in parallel, inside Codex's default 1000 ms
mcp_optional_startup_grace_ms. - Resident memory was about 0.93 GB idle, 1.37 GB at peak with one native TypeScript child started by a query, and 0.54 GB after the query settled.
- A one-query session took about 21 s end to end, mostly model time.
hi updateandhi checkleave no process behind, and no Typegraph process remains after a session ends.
History
Before CLI 6.1.0, Typegraph ran as a local experiment installed by hand with project-local entries, which later disappeared from this checkout's configuration. Serena was evaluated and rejected: configuring it for TypeScript 7.0.2 failed because its typescript-language-server adapter requires tsserver.js. See the Registry research and the closed requirements.
Sources: Typegraph, Codex MCP configuration.