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

@case-framework/survey-assistant

v0.12.0

Published

Shared protocol, engine, and runtime for the CASE survey assistant.

Readme

CASE Survey Assistant

This workspace package exposes isolated protocol, engine, runtime, headless React, and optional localized UI entry points:

import {
  surveyChangeSetSchema,
  surveyAssistantTurnFinalSchema,
  type SurveyChangeSet,
} from "@case-framework/survey-assistant/protocol";

import { buildCapabilityDigest } from "@case-framework/survey-assistant/protocol/digest";

import {
  createSurveyAssistantEngineContext,
  validateSurveyOperations,
} from "@case-framework/survey-assistant/engine";

import {
  defaultSurveyAssistantCapabilities,
  defaultSurveyAssistantCapabilitySet,
} from "@case-framework/survey-assistant/capabilities/default";

import {
  createSurveyAssistantChatHandler,
  createSurveyAssistantSurveyLifecycle,
  createSurveyAssistantSurveyThreadMetadata,
  type SurveyAssistantAuthorize,
} from "@case-framework/survey-assistant/server";

import {
  createSurveyAssistantAgent,
  type SurveyAssistantHistoryCompatibility,
} from "@case-framework/survey-assistant/server/agent";

import {
  SURVEY_ASSISTANT_TOOL_IDS,
  surveyAssistantTools,
} from "@case-framework/survey-assistant/server/tools";

import {
  createSurveyAssistantTaskAgent,
  createSurveyAssistantTaskHandler,
} from "@case-framework/survey-assistant/server/tasks";

import {
  createSurveyAssistantRuntime,
  parseSurveyAssistantConfigurationDocument,
  parseSurveyAssistantEnvironment,
} from "@case-framework/survey-assistant/server/runtime";

import {
  createSurveyAssistantPostgresRuntime,
  createSurveyAssistantPostgresThreadDocumentRepository,
  initializeSurveyAssistantPostgresStorage,
} from "@case-framework/survey-assistant/storage/postgres";

import {
  createSurveyAssistantControllerBridge,
  createSurveyAssistantTaskClient,
  createSurveyAssistantThreadLauncher,
} from "@case-framework/survey-assistant/react/integration";

import { useSurveyAssistantModelCatalog } from "@case-framework/survey-assistant/react";

import {
  ConnectedSurveyAssistantPanel,
  SurveyAssistantPanel,
} from "@case-framework/survey-assistant/ui";

/protocol is the browser-safe runtime owner for wire schemas and inferred types. /protocol/digest keeps stable hashing independently tree-shakeable for Survey UI consumers. /engine derives request-local survey context and owns pure inspection, normalization, validation/simulation, expression compilation, and turn collection. /capabilities/default provides the trusted, versioned capabilities for the standard CASE editor registry.

/server owns the lightweight framework-agnostic Web chat handler, required host authorization contract, request guardrails and context, thread-attachment repository and model-selected native replay, turn-final stream, error/metrics hooks, and packaged Markdown authoring references. /server/tools owns the standard request-context tools, and /server/agent owns their Agent, instructions, thread-scoped Observational Memory defaults, and optional history-compatibility policy for custom memory setups. /server/runtime is the high-level composition layer: it parses a versioned provider/model policy document or the legacy injected environment, resolves the approved model catalog (including optional Azure deployment discovery), applies same-provider chat, task, and memory roles, exposes standard Mastra agents and gateways, and creates the Web handlers. The host still constructs the standard Mastra instance and owns credentials, authorization, storage connection lifecycle, logging, and route files.

/react owns the headless chat session, threads, validated model-catalog loading, remembered model selection, and structural controller proxy. /react/integration is the lightweight controller and one-shot task entry for editor packages that do not need chat transport. /ui owns the reusable panel, transcript, reasoning/tool presentation, prompt and attachment controls, model picker, thread history, and complete English and Dutch defaults. ConnectedSurveyAssistantPanel also owns model-catalog loading and remembered selection for the common case. Import @case-framework/survey-assistant/ui.css once from the host root layout. The stylesheet has no preflight and scopes generated utilities beneath the panel root. A host can pass a partial localization catalog to extend or override the defaults without supplying a complete catalog.

Hosts using /ui must install @base-ui/react@^1.8.0 alongside React and React DOM. Base UI is an optional peer dependency so server and protocol consumers do not need to install it. Use the same Base UI installation for the assistant, survey player, editor, and host components.

<ConnectedSurveyAssistantPanel
  api="/api/survey-assistant/chat"
  applyPolicy="auto"
  controller={assistantController}
  language={language}
  localizations={assistantLocalizations}
  onModelChange={setSelectedModelId}
  resourceId={authenticatedUserId}
  surveyId={surveyId}
  threadApi="/api/survey-assistant/threads"
/>

Host UI can start a fresh assistant thread with an already-submitted prompt. The launcher queues requests made before the panel mounts, which supports replacing a prompt-only new-survey screen with the chat after submission:

const threadLauncher = useMemo(() => createSurveyAssistantThreadLauncher(), []);

const describeNewItem = (prompt: string, parentItemId: string, afterItemId?: string) => {
  setAssistantOpen(true);
  void threadLauncher.startThread({
    prompt,
    uiContext: {
      activeSurface: "new-item",
      focusItemId: parentItemId,
      highlights: [
        {
          kind: "insertion-target",
          itemId: parentItemId,
          label: "Requested item position",
          details: afterItemId ? `Insert after item ${afterItemId}` : "Insert as the first child",
        },
      ],
    },
  });
};

return assistantOpen ? (
  <ConnectedSurveyAssistantPanel
    api="/api/survey-assistant/chat"
    applyPolicy="auto"
    controller={assistantController}
    resourceId={authenticatedUserId}
    threadApi="/api/survey-assistant/threads"
    threadLauncher={threadLauncher}
  />
) : (
  <NewSurveyPrompt onSubmit={(prompt) => describeNewItem(prompt, "root")} />
);

startThread() resolves after the new thread has been selected and its first turn has been accepted by the chat session. uiContext is layered over the controller snapshot for that turn only; it does not mutate editor selection or navigation state. Use typed highlights for transient targets such as an insertion position.

The browser-supplied resourceId is request metadata, not authorization. A production host must derive user, survey, and thread ownership in the server handler's required authorize callback.

For the supported real-app setup, configuration reference, route/auth contract, attachment policy, apply settlement, observability, cleanup, and acceptance checklist, see Real-host integration.

The repository's Survey Editor host keeps its active configuration local. Start from apps/survey-editor/config/survey-assistant.example.yaml and keep provider credentials in the environment variables named by apiKeyEnv.

createSurveyAssistantSurveyLifecycle(...).forSurvey(surveyId, resourceId) provides one shared thread identity, chat authorizer, panel-prop object, and per-user cleanup method so those paths cannot drift onto different survey metadata.

/protocol, /engine, and /capabilities/default may not import React, Next.js, Mastra, AI SDK, survey-ui, or Node-only storage. /protocol has Zod plus the narrow browser-safe survey-core/editor/colors runtime dependency; /engine and /capabilities/default may use the headless survey-elements domain and the full survey-core API. /server is server-only and may import Mastra, AI SDK, and Node APIs, but never React, Next.js, or survey-ui. The separate server entries prevent handler-only consumers from eagerly loading Agent/Memory code. @case-framework/survey-editor-ui owns the optional live-editor bridge, snapshot/apply functions, and snapshot-backed one-shot provider because those functions must operate on its editor instance and editor registry. The assistant package supplies the standard task Web handler and browser executor adapter, so another host does not need to recreate Next server actions or repeat the one-shot method mapping. This package never imports survey-ui.

Custom element packages define a server-safe AssistantElementCapabilityAdapter and attach it as assistantCapability on an ElementRegistryEntry. The entry's define(body) supplies the canonical schema, ownership, slots, activation, and computed dependencies. See Custom survey elements for registration and capability contracts for the optional inspection, validation, and preset hooks.

The composed editor registry validates and caches the attached capabilities once. Server configuration imports ratingAssistantCapability directly and adds it to the trusted capability set; it must not trust capability functions received from a browser snapshot.

pnpm --filter @case-framework/survey-assistant check
pnpm --filter @case-framework/survey-assistant check:release
pnpm benchmark:survey-assistant-operations

check typechecks and builds all entries, copies server references, verifies their source and built import graphs, and runs typed unit/DOM tests plus the real SDK streaming integration tests (with a scripted model, no provider requests). check:release also builds the clean Next host fixture. benchmark:survey-assistant-operations uses the current built engine output to profile maximum-size typed validation and the raw-patch path against a synthetic 5,002-item survey; run build first when source has changed. The optional Postgres entry accepts a host-owned PostgresStore or store configuration; it does not read environment variables, create hidden singletons, or own connection shutdown.

Test boundaries

  • test checks fixtures and runs the Vitest source suite. Its tool-constructor mock deliberately bypasses SDK validation for handler-level negative inputs; the test TypeScript config reflects that mock and keeps schema input/output types. The separate production typecheck uses the real SDK types.
  • test:integration runs built output through native node:test with the real Agent, tools, HTTP handler, stream adapter, transport, and session hook. Only model responses are scripted. Build changed package output first. The editor UI suite also feeds these real streamed candidates through its apply/undo boundary in a separate native ESM process so source-test aliases and mocks cannot replace the SDKs.
  • test:postgres also uses native node:test and requires SURVEY_ASSISTANT_TEST_DATABASE_URL. Use a disposable PostgreSQL database: the test creates a unique schema and drops only that schema in cleanup. It tests isolation, BYTEA roundtrips, deduplication, and concurrent quotas against real PostgreSQL. Missing configuration fails explicitly; this opt-in test is not part of the database-free check command.
  • Live model evaluations remain opt-in. DOM tests exercise events but do not establish browser layout, focus, scrolling, or accessibility acceptance.
SURVEY_ASSISTANT_TEST_DATABASE_URL=postgresql://localhost/assistant_test \
  pnpm --filter @case-framework/survey-assistant test:postgres

Integration Levels

Use the highest level that fits the host; the lower layers remain available for custom authentication, provider policy, UI, or storage.

  • Standard server: parseSurveyAssistantConfigurationDocument plus createSurveyAssistantRuntime, then register its agents and gateways in a normal Mastra instance and call runtime.createHandlers(...).
  • Custom server: compose createSurveyAssistantAgent, individual chat, task, thread, and model handlers, and a custom resolveModel directly.
  • Standard UI: ConnectedSurveyAssistantPanel plus Survey UI's useSurveyEditorAssistantIntegration bridge.
  • Custom UI: use useSurveyAssistantSession, thread/model clients from /react, and controller/task adapters from /react/integration.

The high-level APIs are thin composition helpers over the same exported primitives. They do not introduce a second runtime or hide Mastra.

Importing hosts can optionally require the additional SURVEY_ASSISTANT_ALLOW_EXPERIMENTAL_IDENTITY=true production rollout gate by passing requireExperimentalIdentityOptIn: true to a configuration parser. The option does not choose or authorize an identity, and most authenticated hosts should omit it unless they want that extra deployment switch. See Real-host integration for the exact enablement rules.

Response-variable authoring (survey schema version 3)

Assistant mutations target exact persistent item IDs. Search exposes resolved editor names and breadcrumbs for discovery; names may repeat. Response-slot declarations from the shared element definitions provide persistent IDs, coding names, domains, matrix ownership and computed dependencies. Expressions serialize references as {slotId, method: "get" | "isDefined"}.

Use update-response-settings with naming and settings arrays for atomic scalar names, matrix naming components, option export codes and export defaults. Shared core previews validate names, derived families and projected headers; editor application remains a single normal undoable transaction. The built-in registry supports consent, choice and form matrices alongside scalar inputs and option follow-up content.

One-shot tasks are suggest-response-name (a scalar itemId and slotId) and suggest-response-settings (slotIds and a naming category). Response Settings offers selected-variable or filtered-visible-variable suggestions, validates a before/after preview, and applies only on user action. Categories are fair, survey-pattern, compact, and preferred. All obey the same naming syntax; FAIR guidance is a project convention, not a certification.

Custom elements declare slots, ownership, activation and computed dependencies through their trusted headless ElementDefinition, shared by the assistant and player. Capability adapters supplement those declarations with authoring policy; they do not supply constructors or a separate response schema. Pass the same capability set to buildSurveyAssistantTaskContext, or the editor AI provider/integration's optional capabilities, for custom-variable tasks. The server must continue to supply trusted capabilities independently of browser data.