-
Notifications
You must be signed in to change notification settings - Fork 68
Description
Problem
@dexto/core currently exposes almost its entire API surface through a single root barrel (src/index.ts → export * from every domain module). The only declared subpath export beyond . is ./utils/path.js.
This causes real issues for downstream consumers:
- Browser bundles pull in Node.js code — importing a single type like
ApprovalStatusfrom@dexto/coredrags increateLogger, OpenTelemetry,processreferences, and other server-only modules. This caused aReferenceError: process is not definedindexto-cloud's dashboard becausechat-uiimportedApprovalStatusfrom the root. - No tree-shaking — bundlers can't eliminate unused domains because everything flows through one barrel.
- Unclear public API boundaries — consumers can't tell which modules are meant to be imported independently vs. which are internal implementation details.
The infrastructure to fix this already exists — there are 20+ domain modules with clean barrel index.ts files, and tsup compiles every source file to mirrored dist/ paths. The package.json just doesn't declare the subpaths.
There's even a TODO in src/index.ts:
// TODO: Break down into subpath exports for better tree-shaking
// Consider adding exports like:
// - @dexto/core/telemetry
// - @dexto/core/llm
// - @dexto/core/session
// - @dexto/core/tools
Proposed change
Add a wildcard subpath export to package.json that maps each domain module:
{
"exports": {
".": { "types": "...", "browser": "...", "default": "..." },
"./*": {
"types": "./dist/*/index.d.ts",
"default": {
"import": "./dist/*/index.js",
"require": "./dist/*/index.cjs"
}
},
"./utils/path": {
"import": "./dist/utils/path.js",
"require": "./dist/utils/path.cjs"
},
"./package.json": "./package.json"
}
}This enables per-domain imports that mirror the existing top-level modules:
import { StreamingEvent, StreamingEventName } from '@dexto/core/events';
import { ApprovalStatus, ApprovalRequest } from '@dexto/core/approval';
import { ContentPart } from '@dexto/core/context';
import { TokenUsage } from '@dexto/core/llm';
import { createLogger } from '@dexto/core/logger';
import { DextoAgent } from '@dexto/core/agent';
import { defineTool } from '@dexto/core/tools';Domain modules that become subpaths
All existing src/*/index.ts barrels:
| Subpath | Domain |
|---|---|
@dexto/core/agent |
DextoAgent, agent card, runtime config |
@dexto/core/approval |
ApprovalStatus, ApprovalRequest, ApprovalManager |
@dexto/core/context |
ContentPart, MessageContent, context manager |
@dexto/core/errors |
Base errors, ErrorScope, ErrorType |
@dexto/core/events |
StreamingEvent, event bus, event names |
@dexto/core/hooks |
HookManager, hook types |
@dexto/core/llm |
LLM registry, TokenUsage, providers |
@dexto/core/logger |
createLogger, DextoLogger, transports |
@dexto/core/mcp |
MCPManager, MCP types |
@dexto/core/memory |
MemoryManager, memory types |
@dexto/core/preferences |
Preferences |
@dexto/core/prompts |
PromptManager, prompt schemas |
@dexto/core/resources |
ResourceManager, resource types |
@dexto/core/search |
SearchService |
@dexto/core/session |
ChatSession, SessionManager |
@dexto/core/storage |
StorageManager, blob types |
@dexto/core/systemPrompt |
System prompt manager, contributors |
@dexto/core/telemetry |
Telemetry, OTel config |
@dexto/core/tools |
defineTool, ToolManager, tool types |
@dexto/core/utils |
Path helpers, Zod utils, misc |
@dexto/core/workspace |
WorkspaceManager |
Behavior
- Root import stays unchanged —
import { DextoAgent } from '@dexto/core'continues to work and re-exports everything (backward compatible). - Subpath imports are additive — no breaking change, just new import paths available.
- Browser safety comes naturally — browser code imports from lightweight subpaths like
eventsorapprovalthat don't have Node.js dependencies in their import graph. sideEffects: falseshould be added topackage.jsonto enable bundler tree-shaking.
Prior art
Mastra uses this exact pattern in @mastra/core — wildcard ./* export with explicit overrides for non-standard paths, minimal root barrel, and all their UI/client packages import from subpaths.
Checklist
- Add
./*wildcard export topackage.json - Add explicit overrides for any modules that don't follow
src/<name>/index.tsconvention (e.g../utils/path) - Add
"sideEffects": falsetopackage.json - Remove the TODO comment from
src/index.ts - Verify
@dexto/client-sdkand@dexto/agent-managementstill build (they import from root today) - Update
dexto-cloudconsumers to use subpath imports where it eliminates browser bundle issues