Skip to content

fix(types): make published client declarations portable - #4999

Open
OwenKephart wants to merge 2 commits into
mainfrom
fix/public-declaration-portability
Open

OwenKephart wants to merge 2 commits into
mainfrom
fix/public-declaration-portability

Conversation

@OwenKephart

@OwenKephart OwenKephart commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Published client types can silently become any, and bundled declarations can import files that eve does not ship. Define inspection and health data contracts independently of validators, follow transitive declaration imports during vendoring, and declare optional integration peers. Check documentation import names as well as paths. This is the independently shippable declaration-fix portion of #4930; full entry-point portability coverage remains part of the cleanup stack.

Validation

  • Built eve and emitted declarations.
  • tsc -p packages/eve/tsconfig.json --noEmit passed.
  • Six agent-info unit tests passed, including bidirectional validator/public-type compatibility assertions checked by TypeScript.
  • Two focused scenario tests passed: transitive declaration chunk copying and a packed, isolated client consumer with skipLibCheck: false.
  • The declaration-copy regression failed with the original copier and passed with the repair.
  • All three docs checks and node scripts/guard-invariants.mjs passed.
  • A temporary docs snippet importing a nonexistent, aliased name failed the new name check as expected.
  • Focused lint, formatting, and git diff --check passed. Full integration/scenario and e2e suites were not run locally.
  • The packed client consumer installs the locked AI SDK version, its Zod peer, Node types, and @types/json-schema needed by AI SDK declarations. It first checks eve's data contracts without those packages.

Review follow-through

Addressed all four review findings. Declaration references now use the TypeScript parser, including path directives and import types, without mistaking string literals for imports. Exact normalized schema/interface checks reject optional-field drift; a temporary added field passes the old bidirectional test and fails the new check. The six inspection units and transitive declaration scenario pass. The Connect floor remains 2.5.2 because 2.2 lacks its manifest export; workspace apps now use the catalog version. Typecheck, docs checks, and the invariant guard pass.

Checklist

  • I added tests and documentation where relevant
  • I added a changeset if this touches the published eve package
  • DCO sign-off passes for every commit (git commit --signoff)

Signed-off-by: owenkephart <owen.kephart@vercel.com>

Co-Authored-By: owenkephart <owen.kephart@vercel.com>
@OwenKephart
OwenKephart requested a review from a team as a code owner October 17, 2026 22:25
@vercel

vercel Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
eve-docs Ready Ready Preview, v0 Oct 18, 2026 1:22am UTC
eve-pkg Ready Ready Preview, v0 Oct 18, 2026 1:22am UTC

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Bundle + Package Summary: apps/fixtures/weather-agent

Key takeaways

  • Dependency delta: 8 peer deps added.

Delta vs main (f4e8ef1)

Area Metric Baseline Current Delta
Package Packed tarball 7.66 MB 7.67 MB +8.6 kB ⚠️
Package Unpacked publish size 26.97 MB 26.96 MB -11.1 kB ✅
Package Installed footprint 75.11 MB 75.10 MB -10.4 kB ✅
Package Published files 4171 4180 +9
Package Installed files 8182 8191 +9
Package Installed package instances 34 34 0
Package Distinct installed package names 32 32 0
Package Installed dependency edges 51 51 0
Package Installed optional peer edges 9 17 +8
Runtime Unique function payloads 2 2 0
Runtime Total function bytes 20.77 MB 20.77 MB -120 B ✅
Runtime Public routes 18 18 0
Dependency manifest changes vs main (f4e8ef1)

Peer dependencies

  • Added: @nuxt/kit@^4.0.0 (optional), @nuxt/schema@^4.0.0 (optional), @vercel/connect@^2.5.2 (optional), next@^16.0.0 (optional), react@^19.0.0 (optional), svelte@^5.0.0 (optional), vite@^8.3.1 (optional), vue@^3.5.0 (optional)
Changed function payloads vs main (f4e8ef1) (2)
Function Status Baseline Current Delta Route changes
functions/__server.func changed 10.38 MB 10.38 MB -60 B ✅ none
functions/.well-known/workflow/v1/flow.func changed 10.38 MB 10.38 MB -60 B ✅ none

eve init install

Metric Baseline Current Delta
Installed footprint 113.50 MB 113.49 MB -10.4 kB ✅
Installed packages 97 97 0
dependencies 4 4 0
devDependencies 2 2 0
Dependency package bytes 45.25 MB 45.24 MB -11.1 kB ✅
devDependency package bytes 5.11 MB 5.11 MB 0 B ➖
Build Metadata
  • Preset: vercel
  • Nitro: nitro@3.0.260903-beta
  • Output directory: apps/fixtures/weather-agent/.vercel/output
  • Build metadata timestamp: 2026-10-18T01:23:04.236Z
  • Route aliases: 18 public, 1 internal (19 total aliases)
  • Vercel routes in config: 21
  • Severity legend: 🔴 dominant/large, 🟠 notable, 🟡 watch, ⚪ small
Package Drill-Down

Package Details

  • Package: eve@0.80.1
  • Package directory: packages/eve
  • Tarball: 7.67 MB (eve-0.80.1.tgz)
  • Unpacked payload: 26.96 MB across 4180 published files
  • Installed footprint: 75.10 MB across 8191 installed files
  • Installed root package: 26.96 MB
  • Installed dependencies: 48.14 MB
  • Installed package instances: 34
  • Distinct installed package names: 32
  • Installed dependency edges: 51
  • Installed optional peer edges: 17
  • Runtime dependencies: 2
  • Peer dependencies: 15 (14 optional)

Installed footprint is measured from an isolated temporary npm install of the packed tarball.
Graph metrics read only package.json files in package directories directly beneath a node_modules boundary, including nested boundaries. Each directory is one package instance; distinct names come from those manifests. Dependency edges count each unique name in dependencies or optionalDependencies per instance; optional peer edges count peerDependencies marked optional.

Heavy installed dependencies

  • eve: 26.96 MB (35.9%)
  • @rolldown/binding-linux-x64-gnu: 19.81 MB (26.4%)
  • ai: 8.24 MB (11.0%)
  • zod: 6.15 MB (8.2%)
  • undici: 3.58 MB (4.8%)
Publish payload breakdown
Published file size
🟠 dist/src/compiled/shadcn-registry/index.js       [#####...................] 3.85 MB 14.3%
🟠 dist/src/compiled/@photon-ai/chat-adapter-ime... [###.....................] 2.29 MB 8.5%
🟠 dist/src/compiled/@ai-sdk/code-mode/index.js     [#.......................] 1.03 MB 3.8%
🟡 dist/src/compiled/@vercel/blob/index.js          [#.......................] 604.9 kB 2.2%
🟡 dist/src/compiled/_chunks/workflow/undici-D-I... [#.......................] 521.9 kB 1.9%
🔴 Other published files                            [########################] 18.67 MB 69.3%
Installed footprint breakdown
Installed package size
🔴 eve                             [########################] 26.96 MB 35.9%
🔴 @rolldown/binding-linux-x64-gnu [##################......] 19.81 MB 26.4%
🔴 ai                              [#######.................] 8.24 MB 11.0%
🔴 zod                             [#####...................] 6.15 MB 8.2%
🟠 undici                          [###.....................] 3.58 MB 4.8%
🟠 nitro                           [##......................] 1.89 MB 2.5%
🔴 Other installed packages        [########................] 8.46 MB 11.3%
Runtime dependencies (2)
Package Range Notes
nitro 3.0.260903-beta
undici 8.10.2
Peer dependencies (15)
Package Range Notes
@nuxt/kit ^4.0.0 optional peer
@nuxt/schema ^4.0.0 optional peer
@opentelemetry/api ^1.0.0 optional peer
@vercel/connect ^2.5.2 optional peer
ai catalog:
braintrust ^3.0.0 optional peer
chat ^4.42.0 optional peer
dd-trace ^6.13.0 optional peer
just-bash ^3.1.0 optional peer
microsandbox ^0.5.0 optional peer
next ^16.0.0 optional peer
react ^19.0.0 optional peer
svelte ^5.0.0 optional peer
vite ^8.3.1 optional peer
vue ^3.5.0 optional peer
eve init install drill-down

eve init install details

  • Command: eve init my-agent
  • Package manager: npm
  • Installed footprint: 113.49 MB across 10108 installed files
  • Installed packages: 97 total (91 transitive-only)
  • dependencies: 4 direct packages totaling 45.24 MB
  • devDependencies: 2 direct packages totaling 5.11 MB
  • Other transitive package files: 63.14 MB

Installed footprint is measured from an isolated temporary eve init my-agent using the current packed eve tarball.

Heavy installed dependencies

  • @typescript/typescript-linux-x64: 27.95 MB (24.6%)
  • eve: 26.96 MB (23.8%)
  • @rolldown/binding-linux-x64-gnu: 19.81 MB (17.5%)
  • zod: 9.76 MB (8.6%)
  • ai: 8.24 MB (7.3%)
Installed footprint breakdown
Installed package size
🔴 @typescript/typescript-linux-x64 [########################] 27.95 MB 24.6%
🔴 eve                              [#######################.] 26.96 MB 23.8%
🔴 @rolldown/binding-linux-x64-gnu  [#################.......] 19.81 MB 17.5%
🔴 zod                              [########................] 9.76 MB 8.6%
🔴 ai                               [#######.................] 8.24 MB 7.3%
🟠 undici                           [###.....................] 3.58 MB 3.2%
🔴 Other installed packages         [###############.........] 17.19 MB 15.1%
dependencies (4)
Package Range Installed size Share
@vercel/connect 2.5.2 276.3 kB 0.2%
ai ^7.0.137 8.24 MB 7.3%
eve file:eve-0.80.1.tgz 26.96 MB 23.8%
zod 4.5.4 9.76 MB 8.6%
devDependencies (2)
Package Range Installed size Share
@types/node 24.x 2.61 MB 2.3%
typescript 7.0.2 2.50 MB 2.2%
Function Drill-Down

Payload Size Graph

Unique function payload size and share of total
🔴 functions/.well-known/workflow/v1/flow.func     [########################] 10.38 MB 50.0%
🔴 functions/__server.func                         [########################] 10.38 MB 50.0%

Top Function Payloads

🟠 functions/.well-known/workflow/v1/flow.func • 1 public route • 10.38 MB
Metric Value
Public routes /.well-known/workflow/v1/flow
Runtime nodejs24.x
Handler index.mjs
Payload 10.38 MB
Function files 10.38 MB across 122 files
Traced dependencies 0 B
Signal 🟠 Bundled file _chunks/vercel.web.mjs is 2.38 MB (22.9%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 _chunks/vercel.web.mjs                         [############............] 2.38 MB 22.9%
🟠 _libs/undici.mjs                               [#####...................] 1.01 MB 9.7%
🟡 _chunks/sandbox3.mjs                           [####....................] 815.4 kB 7.9%
🟡 _chunks/compiled-artifacts-instrumentation.mjs [####....................] 734.8 kB 7.1%
🟡 _chunks/token-util-Bla5Z0G9.mjs                [####....................] 704.7 kB 6.8%
🔴 Other bundled files                            [########################] 4.74 MB 45.7%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x",
  "maxDuration": "max",
  "experimentalTriggers": [
    {
      "type": "queue/v2beta",
      "topic": "__eve776561746865722d6167656e74_wkf_workflow_*",
      "consumer": "default",
      "retryAfterSeconds": 5,
      "initialDelaySeconds": 0
    }
  ],
  "environment": {
    "WORKFLOW_PRECONDITION_GUARD": "1"
  }
}

🟠 functions/__server.func • 17 public routes, 1 internal alias • 10.38 MB
Metric Value
Public routes /
/.well-known/workflow/v1/webhook/[token]
/eve/v1/callback/[token]
/eve/v1/connections/[name]/callback/[attemptId]/[token]
/eve/v1/connections/[name]/callback/[token]
/eve/v1/health
/eve/v1/info
/eve/v1/session
/eve/v1/session/[parentSessionId]/subagents/[callId]/[childSessionId]/stream
/eve/v1/session/[sessionId]
/eve/v1/session/[sessionId]/cancel
/eve/v1/session/[sessionId]/clear
/eve/v1/session/[sessionId]/compact
/eve/v1/session/[sessionId]/reset
/eve/v1/session/[sessionId]/stream
/eve/v1/session/[sessionId]/stubs
/eve/v1/task-input/[token]
Internal aliases /__server
Runtime nodejs24.x
Handler index.mjs
Payload 10.38 MB
Function files 10.38 MB across 122 files
Traced dependencies 0 B
Signal 🟠 Bundled file _chunks/vercel.web.mjs is 2.38 MB (22.9%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 _chunks/vercel.web.mjs                         [############............] 2.38 MB 22.9%
🟠 _libs/undici.mjs                               [#####...................] 1.01 MB 9.7%
🟡 _chunks/sandbox3.mjs                           [####....................] 815.4 kB 7.9%
🟡 _chunks/compiled-artifacts-instrumentation.mjs [####....................] 734.8 kB 7.1%
🟡 _chunks/token-util-Bla5Z0G9.mjs                [####....................] 704.7 kB 6.8%
🔴 Other bundled files                            [########################] 4.74 MB 45.7%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x"
}

Build Timing: e2e/fixtures/agent-tools-sandbox

This is an informational timing measurement inside eve build, from preflight through publication. Output-size measurement and profile writing are excluded.

Build mode: deployable Vercel build with sandbox template prewarm included.

  • Build pipeline: 3.80 s -> 3.74 s (-64.0 ms) vs main (f4e8ef1).
  • Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `main (f4e8ef1)`
Phase Baseline Current Delta
extension.check 13.2 ms 17.6 ms +4.4 ms
project.resolve 6.3 ms 0.4 ms -5.9 ms
workspace.create 0.8 ms 0.5 ms -0.3 ms
host.prepare 804.3 ms 704.2 ms -100.1 ms
vercel.service-prefix.resolve 2.2 ms 2.2 ms 0.0 ms
nitro.create 678.7 ms 681.7 ms +3.0 ms
sandbox.prewarm 394.2 ms 372.1 ms -22.1 ms
nitro.cache.prepare 0.2 ms 0.2 ms 0.0 ms
nitro.prepare 0.7 ms 0.7 ms 0.0 ms
nitro.public-assets 0.8 ms 0.8 ms 0.0 ms
nitro.prerender 0.6 ms 0.6 ms 0.0 ms
nitro.bundle 1.76 s 1.81 s +46.6 ms
nitro.cache.write 0.4 ms 0.4 ms 0.0 ms
vercel.workflow-function.materialize 53.8 ms 57.7 ms +3.9 ms
agent-summary.emit 0.6 ms 0.6 ms 0.0 ms
connect-manifest.emit 0.3 ms 0.3 ms 0.0 ms
nitro.close 0.2 ms 0.2 ms 0.0 ms
output.publish 3.5 ms 3.8 ms +0.3 ms
workspace.remove 2.8 ms 2.8 ms 0.0 ms

Comment thread docs/reference/typescript-api.md Outdated
| `eve/vue` | `vue` 3.5 or later in v3 |
| `eve/svelte` | `svelte` 5 |
| `eve/next` | `next` 16 and `react` 19 |
| `eve/vite` | `vite` 8.3.1 or later in v8 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eve/vite isn't an entry point: packages/eve/package.json#exports has no ./vite. The Vite-backed entries are eve/sveltekit and eve/tanstack (both import type ... from "vite"), and neither is in this table. Since this is a table rather than a fenced snippet, the new name check in check-doc-snippets.mjs won't catch it. Suggest replacing this row with eve/sveltekit and eve/tanstack.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected the table to name eve/sveltekit and eve/tanstack. The import-name checker and all docs checks pass.

Comment on lines +21 to +22
expectTypeOf<AgentInfoResult>().toMatchTypeOf<ValidatedInfo>();
expectTypeOf<ValidatedInfo>().toMatchTypeOf<AgentInfoResult>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking toMatchTypeOf in both directions doesn't catch drift in optional fields. { a: string } and { a: string; b?: number } are assignable to each other, so if someone adds an optional field to only the schema or only agent-info-types.ts, this test still passes. Most of the hand-written contract is optional fields (mountId, description, binding, outputSchema, endpoint, ...), so this is the drift most likely to happen. expectTypeOf<AgentInfoResult>().toEqualTypeOf<ValidatedInfo>() after the ReadonlyDeep normalization makes it an exact check. Same for HealthResult. As a bonus, toMatchTypeOf is deprecated in current expect-type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced assignability checks with exact recursive shape equality, flattening interface/intersection representation while preserving keys and modifiers. A temporary optional-field addition passes the old bidirectional check and fails the new assertion; restored types pass.

Comment on lines +137 to +142
const uncommented = sourceText.replace(
/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')|\/\*[\s\S]*?\*\/|\/\/[^\n]*/gu,
(_match, literal) => literal ?? "",
);
const references = uncommented.matchAll(
/\b(?:from\s*|import\s*\(\s*|import\s*)["'](\.[^"']+)["']|<reference\s+path=["'](\.[^"']+)["']/gu,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment stripper's //[^\n]* branch also removes /// <reference path="./x.d.ts" /> lines. That means the <reference\s+path=...> alternative on line 142 can never match, and a path-referenced declaration is silently left out of the package (the original text, directive included, is still copied). Going the other way, string literals are kept and then searched as if they were code, so a declaration type like 'request from "./x"' gets treated as an import and fails the build with "imports missing declaration".

It might be simpler to drop both regexes and use ts.preProcessFile(sourceText, true, true): its importedFiles (which includes import() types) plus referencedFiles gives you exactly this set, already syntax-aware. It would also help to add a /// <reference path> case to the new copier scenario.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the comment/import regex with TypeScript syntax traversal and referencedFiles. The scenario now covers a path directive, a misleading import-like string literal, cycles, and an external import() type; it passes.

Comment thread packages/eve/package.json
"@nuxt/kit": "^4.0.0",
"@nuxt/schema": "^4.0.0",
"@opentelemetry/api": "^1.0.0",
"@vercel/connect": "^2.5.2",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ^2.5.2 floor conflicts with workspace consumers of eve: workspace:* that pin @vercel/connect to 2.2.0: apps/frameworks/next/package.json:16 and apps/docs/package.json:92. Optional peers are still range-checked when they're installed, so these now produce unmet-peer warnings, and they'd fail under strict peer validation. Either bump those apps to 2.5.2 (the catalog version), or set the floor to whatever version first shipped @vercel/connect/manifest, which src/internal/external-resources.ts resolves.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed resolved by 863da68: apps/frameworks/next and apps/docs now pull @vercel/connect from catalog:, which is pinned to 2.5.2 in pnpm-workspace.yaml and satisfies eve's ^2.5.2 optional-peer floor. The remaining apps/templates/* consumers use the ^2.4.0 range (not an exact 2.2.0 pin), so they resolve to 2.5.2 and don't trip the peer check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept the 2.5.2 floor: the installed 2.2.0 packages do not export /manifest. Both workspace consumers now use the catalog version.

Signed-off-by: owenkephart <owen.kephart@vercel.com>

Co-Authored-By: owenkephart <owen.kephart@vercel.com>

This branch was successfully deployed

2 active deployments
Preview – eve-pkg — 863da685 Deployed Oct 18, 2026 by vercel[bot]
Preview – eve-docs — 863da685 Deployed Oct 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant