Repository navigation
feat: index an npm package's type-declaration surface in a sandbox (deferred from #43) #158
Description
What
Keep "return the TypeScript declaration surface of an exact npm package without executing it" as a Code API capability. #43 built it end to end — capability-bound tarball fetch, SHA-512 integrity checked before decompression, an in-memory unpack that refuses links, devices, escaping paths and decompression bombs, a fresh network-disabled NsJail with route-scoped cgroup/CPU/wall limits around the web-tree-sitter parse, and deterministic files/symbols/imports with rejection counters and resource usage — and it was approved. It has no consumer today, so it is deferred rather than merged.
Why it must not be lost
Coding agents do this out of the box: Claude Code and Codex read a dependency's .d.ts files from a local node_modules to learn an API before writing against it. A hosted agent has no node_modules. A sandboxed, deterministic answer to "what does zod@3.23.8 export" is the equivalent for agents that run through the Code API.
Placement is the open question
Two homes, not mutually exclusive:
- On-demand route in the Code API (📟 feat: Index NPM Type Declarations #43 as designed). Stateless, any
name@version, isolated per request. Serves ad-hoc questions about packages that no indexed repository depends on. - Part of the code-graph indexing process. LibreChat's code-graph indexer already acquires every registry package named by an indexed repository's lockfile under the same threat model — integrity verified before a byte is written, a purpose-written tar reader that accepts regular files only, caps on tarball, unpacked, entry and file sizes, nothing executed, anonymous requests only so a private package fails instead of leaking into a shared cache — and links the declarations into the graph, where agents already query them. What it lacks from 📟 feat: Index NPM Type Declarations #43 is process isolation around the parser and an entry point for packages outside any lockfile.
Leaning: the indexer is the primary home, because the result becomes queryable, versioned and shared across agents. The route earns a merge when a consumer needs packages outside any indexed repository. Decide when that consumer appears.
State when deferred (2026-09-07)
- 📟 feat: Index NPM Type Declarations #43: draft, approved (dustinhealy, 2026-09-02), 2 commits, +2,743 / −16 over 43 files, 69 commits behind
main. - Conflicts with
mainin 9 wiring files:api/src/api/v2.ts,api/src/config.ts,docker-compose.yaml,service/openapi.yml,service/src/api-server.ts,service/src/local-api.ts,service/src/secure-startup.test.ts,service/src/service-api.ts,service/src/worker-server.ts. The npm-unit module itself is untouched by the drift.
To resume
- Name the consumer and pick the home above.
- Route: rebase 📟 feat: Index NPM Type Declarations #43 across the 9 wiring files (dispatch, config, compose, OpenAPI, the three servers, the startup test), re-run the contract, dispatch, archive-hardening and egress tests, re-review.
- Indexer: add an on-request
name@versionentry point next to the lockfile-driven one, and run the parser under the same isolation 📟 feat: Index NPM Type Declarations #43 uses.
Activity