Appearance
Chat package boundaries
Chat (and chat-component) sit at a particular position in the dependency graph: above the framework (@open-matrix/core), below applications that embed it (Director). This page is the explicit list.
Chat app — allowed dependencies
chat/package.json dependencies:
json
"highlight.js": "^11.11.1",
"katex": "^0.16.40",
"marked": "^17.0.5",
"marked-katex-extension": "^5.1.7",
"mermaid": "^11.13.0"devDependencies includes @open-matrix/core (workspace:*) for type checking and Vite.
What that means
- Render libs are direct deps. Markdown/KaTeX/highlight.js/mermaid are bundled into the chat browser bundle; they are required for
mx-markdown-viewer,mx-code-viewer, etc. @open-matrix/coreis a workspace dev-dep. Type-checking against the source. At build time, Vite resolves imports through the workspace.- No
@open-matrix/agents,@open-matrix/inference,@open-matrix/observability,@open-matrix/factotum. Chat reaches those viaRequestReplyonly; it never imports their source. - No
@open-matrix/director,@open-matrix/smithers,@open-matrix/flowpad. Chat is below them; they may consumechat-component, never the other way.
chat-component — same set
chat-component/package.json declares the same dependencies. The two packages are intentionally aligned at the dependency level so they produce equivalent browser bundles for the shared element set, plus chat-component adds its own surface/.
Forbidden imports
Per CLAUDE.md Coding Standards:
- No cross-package
../../imports — only declared npm dependencies. - TypeScript strict mode — no
any, noas any. - No
console.log— useactorLog()for bus-native logging.
The vite.config.ts for both packages adds aliases that resolve @open-matrix/core/* to source in dev (for HMR) and to the built dist in production. Anything that escapes those aliases is suspect.
Runtime vs browser split
Chat is a hybrid package: same source builds two outputs.
| Output | Tsconfig | Purpose |
|---|---|---|
dist/browser/ | tsconfig.json | Browser custom elements, services, bootstrap. |
dist/runtime/ | tsconfig.runtime.json | Runtime-side actor declarations consumed by mx-cli / Host Service. |
The runtime build excludes anything that requires the DOM. The browser build excludes Node-only modules. vite.config.ts and vite.runtime.config.ts are separate; build.mjs orchestrates both.
When you add code to chat/src/, decide which build it belongs to:
- DOM/CustomElement classes → browser build only.
- Headless actors that the runtime instantiates (
ChatConversationProxy,ChatExportService) → runtime build, but their interface is also visible to the browser viaservices/impl/*for the standalone-local mode.
Manifest declarations enforce the boundary
chat/matrix.json:
json
{
"class": "hybrid",
"namespace": "chat",
"root": { "type": "MatrixChatApp", "export": "MatrixChatApp", "mount": "chat", "surface": "browser" },
"runtime": {
"language": "typescript",
"entry": "./dist/runtime/index.js",
"browserEntry": "./dist/browser/register-elements.js",
"bootstrapEntry": "./dist/browser/bootstrap.js",
"environments": ["browser", "headless-dom", "runtime"],
"executionClassCompatibility": [
"shared_host_service", "dedicated_process",
"container", "isolate", "remote_managed_service"
]
},
"components": [...9 headless services...],
"consumes": [...6 service contracts...],
"permissions": { "fsPolicy": "none", "network": true, "subprocess": false, "env": false }
}Key facts:
class: "hybrid"— has both browser and runtime sides.environments: ["browser", "headless-dom", "runtime"]— the runner picks the matching environment for the runtime side.permissions.fsPolicy: "none"— Chat never reads or writes the filesystem at runtime.permissions.subprocess: false,env: false— Chat does not spawn processes or read env vars.permissions.network: true— necessary for the bus (NATS-WS) and the markdown libs that fetch fonts.
The consumes[] list declares which IChat*Service contracts the package needs. Required: IChatConversationService, IChatComponentLibraryService, IChatSessionStateService. Optional: identity, preferences, MCP.
Surface declaration (chat-component only)
chat-component/matrix.json adds:
json
"surfaces": {
"conversation": {
"tag": "conversation-surface",
"module": "./dist/browser/surface/register-surface.js",
"route": "/apps/chat-component/surface/register-surface.js",
"description": "Embeddable conversation surface plugin loaded by host shells (Director, etc.) via dynamic import"
}
}This is metadata for future host-side import-map work (HARVEST-040). It is currently informational.
See also
Source:
projects/matrix-3/packages/chat/package.json,chat/matrix.json,chat/vite.config.ts,chat-component/matrix.json.