npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@meistrari/chat-nuxt

v1.5.1

Published

Nuxt module that adds a complete AI chat interface to your app. Powered by Tela's agent API — conversations, message streaming, file uploads, workspace settings, all out of the box.

Readme

@meistrari/chat-nuxt

Nuxt module that adds a complete AI chat interface to your app. Powered by Tela's agent API — conversations, message streaming, file uploads, workspace settings, all out of the box.

Installation

pnpm add @meistrari/chat-nuxt

Required: Vue dedupe via pnpm overrides

@meistrari/tela-build pins [email protected] as a direct dependency, which collides with the Vue that Nuxt installs. Without an override, pnpm installs two Vue copies and you'll hit runtime errors such as root.ce._hasShadowRoot is not a function when custom elements register against one Vue and mount against the other.

Until tela-build is published with Vue as a peer dependency, pin a single Vue version in your consumer package.json:

{
  "pnpm": {
    "overrides": {
      "vue": "3.5.33"
    }
  }
}

Keep this entry until @meistrari/tela-build moves Vue to peerDependencies — at that point the override becomes unnecessary and should be removed.

Setup

1. Register the modules

// nuxt.config.ts
export default defineNuxtConfig({
    modules: [
        '@meistrari/auth-nuxt', // must come before chat-nuxt
        '@meistrari/chat-nuxt',
    ],

    ssr: false,

    chatNuxt: {
        telaApiUrl: process.env.TELA_API_URL,
        agentApiUrl: process.env.AGENT_API_URL,
        authApiUrl: process.env.AUTH_API_URL,
        vaultUrl: process.env.VAULT_URL,
        databaseUrl: '', // leave empty to use the bundled pglite database
        features: {
            usage: true,
            generateTitle: false,
            credentials: false,
        },
        validateConfig: 'warn',
    },

    telaAuth: {
        apiUrl: process.env.AUTH_API_URL ?? '',
        application: {
            enabled: true,
            applicationId: process.env.APPLICATION_ID ?? '',
            redirectUri: process.env.AUTH_REDIRECT_URI ?? 'http://localhost:3000/auth/callback',
            dashboardUrl: process.env.AUTH_DASHBOARD_URL ?? '',
        },
    },
})

2. Module options

Every chatNuxt.* URL accepts the value inline, or you can leave the option empty and set the matching env var. Resolution order: module option → existing runtimeConfig → env var → empty (or pglite default for databaseUrl).

| Option | Required | Env fallback | Description | |--------|----------|--------------|-------------| | telaApiUrl | ✅ Always | TELA_API_URL | Tela platform API base URL. | | agentApiUrl | ✅ Always | AGENT_API_URL | Agent runtime base URL the chat streams from. | | authApiUrl | ✅ Always | AUTH_API_URL | Auth API base URL used to verify session tokens. | | vaultUrl | ✅ Always | VAULT_URL | Vault API base URL used for file uploads and resolution. | | databaseUrl | 🔧 Optional | DATABASE_URL | Postgres connection string. Falls back to a file-backed pglite database for local dev. | | features | 🔧 Optional | — | Feature toggles (see below). usage defaults to true; the rest default to false. | | validateConfig | 🔧 Optional | — | false (default), 'warn', or 'error'. Warns or fails fast when required runtime config is missing for the enabled features. |

3. Set environment-only secrets

These never appear in module options — set them via .env, Infisical, etc. Whether each one is required depends on which features are enabled.

| Variable | Required when | Description | |----------|---------------|-------------| | AUTH_API_SECRET | features.usage: true | Bearer token chat-nuxt uses to call the Auth API to resolve workspace billing info for the usage feature. | | TELA_API_KEY | features.generateTitle: true | Authenticates the auto-title-generation endpoint, which executes a Meistrari-owned Tela canvas server-side. | | CHAT_APP_SERVICE_KEY | features.credentials: true | Server-to-server X-Service-Key used when chat-nuxt resolves workspace credentials (POST /workspaces/:id/credentials/resolve). | | VAULT_S3_BUCKET | 🔧 Optional | SSRF hardening: when set, /api/vault/permalink-metadata only follows S3 redirects to <bucket>.s3*.amazonaws.com. Recommended in production. |

4. Features

usage defaults to true — the chat experience always tracks per-conversation usage out of the box. generateTitle and credentials default to false and layer on optional behavior with their own runtime requirements.

| Feature | What it does | Adds to required config | |---------|--------------|-------------------------| | usage | Per-conversation token & cost tracking, daily aggregated reports, and the usage tab UI surface. | AUTH_API_SECRET | | generateTitle | Auto-generates conversation titles from the first user message via a Tela canvas. Without this, titles fall back to a truncated prefix of the message. | TELA_API_KEY | | credentials | Resolves workspace-level credentials and injects them into agent calls so tools can authenticate as the workspace. | CHAT_APP_SERVICE_KEY |

Set chatNuxt.validateConfig to 'warn' to log a warning when keys for an enabled feature are missing, or 'error' to fail fast at module setup. The check is off by default since some deployments inject runtime config after build.

Local mode (no database)

When databaseUrl is empty, chat-nuxt runs an embedded pglite instance — Postgres compiled to WASM, in-process, file-backed at <rootDir>/.data/chat-nuxt.db. Migrations are applied automatically on first boot. Tables live under a dedicated chat Postgres schema so the database can be safely shared with the host app's own Drizzle setup.

This mode is intended for local development, demos, and single-instance prototypes. Caveats:

  • Single-process only. Multi-instance deployments (e.g. Railway with replicas > 1) will see divergent local databases — use real Postgres.
  • Node runtime only. Pglite needs a filesystem. It won't run on Cloudflare Workers / Vercel Edge.
  • Roughly 4 MB of WASM is loaded at server startup. Postgres consumers don't pay this cost (the import is dynamic).

To explicitly opt into pglite at a custom path: databaseUrl: 'pglite:/var/data/chat.db' or databaseUrl: 'file:./mydata/chat.db'.

5. Setup app.vue

<!-- app.vue -->
<template>
    <NuxtPage />
    <AppStatusToast />
</template>

AppStatusToast, Markstream styles, code block styles, and math delimiter defaults are auto-registered by the module.

6. Use it

<!-- pages/index.vue -->
<template>
    <div h-screen>
        <MeistrariChatEmbed />
    </div>
</template>

The chat workspace is resolved from the authenticated activeOrganization provided by @meistrari/auth-nuxt.

Chat runtime modes

<MeistrariChatEmbed /> has two mutually exclusive runtimes:

  • Default chat mode uses the Agent API, workspace settings, model selection, optional feature flags, and the authenticated workspace.
  • Tela agent mode uses a configured Tela agent directly. Pass telaAgentId; the embed sends user messages to POST /agent/:id/run, polls GET /agent/sessions/:sessionId, and ends sessions with DELETE /agent/sessions/:sessionId.
<MeistrariChatEmbed tela-agent-id="agent_123" />

Host apps can also provide Tela agent inputs directly. When telaAgentInputs is non-null, the chat sends those inputs with each agent run and does not render the agent variables panel.

<MeistrariChatEmbed
    tela-agent-id="agent_123"
    :tela-agent-inputs="[
        { type: 'text', name: 'customer_id', content: customerId },
    ]"
/>

In Tela agent mode, workspaceSettings, features, and user are not accepted by the public prop contract. The Tela agent owns runtime configuration and identity for execution. Model selection and the usage/debug UI surfaces are also hidden.

Embedding in Your Layout

The main use case: drop the chat inside your existing app UI.

<template>
    <div class="my-app-layout">
        <MyHeader />

        <main>
            <!-- Chat embedded in a card -->
            <div style="height: 600px" class="rounded-2xl overflow-hidden border">
                <MeistrariChatEmbed
                    v-model:conversation-id="activeConversation"
                    :hide-sidebar="true"
                    :loading-messages="['Buscando contratos', 'Lendo documentos', 'Preparando resposta']"
                    loading-messages-mode="ordered"
                />
            </div>
        </main>
    </div>
</template>

Key props for embedding:

  • :hide-sidebar="true" — removes the conversation list, keeps just the chat
  • v-model:conversation-id — sync the active conversation with your app's state
  • :initial-conversation-id — open a specific conversation on mount

<MeistrariChatEmbed> Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | hideSidebar | boolean | false | Hide conversation list sidebar | | conversationId | string \| null | null | Controlled conversation (supports v-model) | | initialConversationId | string \| null | null | Open this conversation on mount | | telaAgentId | string | — | Use Tela agent mode for this embed | | telaAgentInputs | TelaAgentExecutionInput[] \| null | undefined | Inputs sent with each Tela agent run; hides the variables panel when non-null | | workspaceSettings | WorkspaceSettings \| null | null | Override settings from host app | | user | ChatActor \| null | null | Override current user display info | | features | Partial<ChatFeatureConfig> | {} | Toggle optional features | | loadingMessages | string[] \| null | Default chat messages | Override pending-response messages | | loadingMessagesMode | 'ordered' \| 'random' \| null | 'ordered' | Show custom messages sequentially or randomly |

loadingMessagesMode only applies when loadingMessages has at least one non-empty message.

Events:

| Event | Payload | Description | |-------|---------|-------------| | update:conversationId | string \| null | Active conversation changed |

Optional: Feature Flags

<MeistrariChatEmbed> accepts a :features prop with four optional toggles. All default to false. The host owns the policy — hardcode them, gate by user role, or wire them through a feature-flag provider of your choice.

| Flag | Effect | |------|--------| | showUsageTab | Usage tab in the chat topbar (per-conversation token/cost stats) | | showDebugOption | Debug entry in the topbar overflow menu | | showModelSelector | Model picker inside the message input | | showCancelButton | "Stop generation" button while a response streams |

Static example:

<MeistrariChatEmbed :features="{ showUsageTab: true, showCancelButton: true }" />

With PostHog

chat-nuxt ships a small PostHog helper for hosts that want to gate flags dynamically. The flag names live in your app — chat-nuxt has no opinion about them.

  1. Add to nuxt.config.ts:
runtimeConfig: {
    public: {
        posthogPublicKey: process.env.POSTHOG_PUBLIC_KEY ?? '',
        posthogHost: process.env.POSTHOG_HOST ?? '',
        posthogDefaults: process.env.POSTHOG_DEFAULTS ?? '2026-01-30',
    },
},
  1. Initialize in app.vue:
<script setup lang="ts">
const { posthogPublicKey, posthogHost, posthogDefaults } = useRuntimeConfig().public
const { user, activeOrganization } = useTelaApplicationAuth()

onMounted(async () => {
    if (!posthogPublicKey || !posthogHost) return
    await initPosthog(posthogPublicKey, posthogHost, posthogDefaults)
    if (user.value) identifyPosthogUser(user.value)
    if (activeOrganization.value) setPosthogWorkspace(activeOrganization.value)
})
</script>
  1. Thread the flags into the embed:
<script setup lang="ts">
const { isFeatureEnabled } = useFeatureFlags()

const features = computed(() => ({
    showUsageTab: isFeatureEnabled('enable-usage-tab'),
    showDebugOption: isFeatureEnabled('enable-debug-mode'),
    showModelSelector: isFeatureEnabled('enable-model-selector'),
    showCancelButton: isFeatureEnabled('enable-cancel-generation'),
}))
</script>

<template>
    <MeistrariChatEmbed :features="features" />
</template>

Optional: Custom Workspace Settings

By default, workspace settings (system prompt, context files, tools) are managed via the module's built-in UI and stored in PostgreSQL.

You can override this in two ways:

Via props (simple)

Pass settings directly from your host app:

<MeistrariChatEmbed
    :workspace-settings="{
        workspaceId: 'ws_123',
        systemMessage: 'You are a helpful assistant for Acme Corp.',
        contextFiles: null,
        canvasTools: null,
        knowledgeSources: null,
        externalSkills: null,
        createdAt: new Date(),
        updatedAt: new Date(),
    }"
/>

Via server resolver (advanced)

Create a file at server/chat/resolve-workspace-settings.ts in your app. The module auto-discovers it and calls it for every chat request:

// server/chat/resolve-workspace-settings.ts
import type { H3Event } from 'h3'

export default async function resolveWorkspaceSettings(
    event: H3Event,
    context: { workspaceId: string; user: { id: string; email: string } },
) {
    const settings = await fetchFromYourAPI(context.workspaceId)
    return {
        systemMessage: settings.prompt,
        contextFiles: settings.files,
        canvasTools: null,
        knowledgeSources: null,
        externalSkills: null,
        updatedAt: new Date(),
    }
}

<ChatConfigurationModal>

A reusable settings modal (system prompt, context files, Tela workstations, Tela skills, external skills, credentials) that any host app can open from any button. By default, the modal uses useWorkspaceSettings() to fetch and persist settings. If the host passes the settings prop, the host owns workspace settings state and persistence.

<script setup lang="ts">
import type { ChatConfigurationTab } from '@meistrari/chat-nuxt/types/workspace-settings'

const open = ref(false)
const initialTab = ref<ChatConfigurationTab>('personalization')

function openSettings(tab: ChatConfigurationTab = 'personalization') {
    initialTab.value = tab
    open.value = true
}
</script>

<template>
    <button @click="openSettings()">
        Configurações
    </button>

    <ChatConfigurationModal
        v-model:open="open"
        :initial-tab="initialTab"
    />
</template>

| Prop | Type | Default | Description | |------|------|---------|-------------| | open | boolean | — | Modal visibility (supports v-model:open) | | settings | WorkspaceSettings \| null | undefined | Optional host-controlled settings. Omit this prop to let the modal fetch and persist via useWorkspaceSettings(); pass null or a settings object to make the host own state and persistence | | initialTab | ChatConfigurationTab | 'personalization' | Tab to open on | | saving | boolean | false | Host-controlled spinner/disable while persistence is in flight |

| Event | Payload | Description | |-------|---------|-------------| | update:open | boolean | Modal open state changed | | save | ChatConfigurationSavePayload | Emitted only when the host passes settings; diff of the changed fields plus onSaved; host persists (e.g. via useWorkspaceSettings().updateSettings()), calls onSaved after persistence succeeds, and closes the modal |

The credentials tab manages its own data via the module's /api/workspace/credentials endpoints and is never part of the save payload.

What's Included

The module auto-registers everything — no manual imports needed:

  • Components: full chat UI, message bubbles, tool widgets (code, search, files), markdown rendering, file previews
  • Composables: useChat, useConversations, useWorkspaceSettings, useFileUpload, useFeatureFlags, and more
  • Server routes: conversation CRUD, message streaming, workspace settings, vault file storage, GitHub integration
  • Database: conversations, messages, usage tracking (Drizzle ORM + PostgreSQL)

Package Dependencies

Installing @meistrari/chat-nuxt installs the runtime packages used by the layer. The host Nuxt app still owns the Nuxt and Vue versions.

| Package | Version | Purpose | |---------|---------|---------| | @meistrari/auth-nuxt | 3.5.0 | Authentication (required) | | @meistrari/tela-build | ^1.30.0 | UI component library (Nuxt layer) | | @sentry/nuxt | ^10.0.0 | Client-side error capture used by chat composables | | @iconify/vue | ^5.0.0 | Icon rendering support | | @vueuse/core | ^12.8.0 | Runtime composables used by chat UI | | @vueuse/components | ^12.8.0 | VueUse component peer expected by the shared runtime | | h3 | ^1.15.0 | Server route utilities provided by Nuxt/Nitro | | markstream-vue | 0.0.3-beta.6 | Markdown streaming renderer | | motion | ^11.13.0 | Animation component runtime | | nitropack | ^2.10.0 | Runtime config and task utilities provided by Nuxt/Nitro | | virtua | ^0.42.0 | Virtualized list runtime expected by shared UI | | vue-i18n | ^11.0.0 | Internationalization runtime expected by shared UI |

Peer dependencies:

| Package | Version | Purpose | |---------|---------|---------| | nuxt | ^3.17.0 | Host framework | | vue | ^3.5.0 | Host Vue runtime |