Skip to content

feat: index an npm package's type-declaration surface in a sandbox (deferred from #43) #158

Description

@danny-avila

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:

  1. 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.
  2. 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 main in 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

  1. Name the consumer and pick the home above.
  2. 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.
  3. Indexer: add an on-request name@version entry point next to the lockfile-driven one, and run the parser under the same isolation 📟 feat: Index NPM Type Declarations #43 uses.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions