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

@lumifai/harness

v0.2.1

Published

Lumif's thin harness factory around Mastra's `AgentController` runtime. The controller is shared; each conversation is owned by a Mastra `Session`. Server integrations add scoped identity, durable lifecycle, reconnect, and transport behavior.

Downloads

248

Readme

@lumifai/harness

Lumif's thin harness factory around Mastra's AgentController runtime. The controller is shared; each conversation is owned by a Mastra Session. Server integrations add scoped identity, durable lifecycle, reconnect, and transport behavior.

Layered install

  1. Core — @lumifai/harness, @lumifai/harness-protocol
  2. Presets — @lumifai/harness-presets
  3. Tool packs — individual @lumifai/harness-tool-pack-* packages
  4. Server — @lumifai/harness-server, @lumifai/harness-server-fastify, @lumifai/harness-server-nest
  5. Client / React — @lumifai/harness-client, @lumifai/harness-react, @lumifai/harness-react-mantine

Usage

import { LibSQLStore } from '@mastra/libsql';
import { createLumifHarness } from '@lumifai/harness';
import { createPresetHarnessConfig, createPresetWorkspace } from '@lumifai/harness-presets';

const presets = createPresetHarnessConfig({
  includeRequestAccess: true,
});

const controller = createLumifHarness({
  id: 'my-service-agent',
  storage: new LibSQLStore({ url: 'file:./data.db' }),
  workspace: createPresetWorkspace({
    workspaceMode: 'local',
    sandboxEnabled: true,
  }),
  modes: presets.modes,
  subagents: presets.subagents,
  tools: presets.tools,
});

await controller.init();
const session = await controller.createSession({
  id: 'session-1',
  ownerId: 'user-1',
  resourceId: 'resource-1',
});
await session.sendMessage({ content: 'Hello!' });

workspace is required. Everything else is forwarded to Mastra's harness and can be overridden as needed.

Production defaults

The server wrapper in @lumifai/harness-server makes persistence and tenancy explicit:

  • storage defaults to a local LibSQL file store under the workspace path
  • memory defaults to new Memory({ storage }), but you can pass any Mastra memory or a factory
  • threadLock can be supplied for multi-pod / multi-process coordination
  • contextResolver lets adapters inject tenantId, userId, resourceId, sessionId, threadId, and arbitrary request context
  • authorize lets adapters enforce route-level access control before state changes or reads
  • allowClientResourceId is false by default so resource scope comes from server context, not the browser
  • /healthz and /readyz are exposed by the Fastify server

Workspace modes

createPresetWorkspace() and createHarnessServerWorkspace() make the workspace shape explicit:

  • workspaceMode: 'local' - LocalFilesystem plus optional LocalSandbox
  • workspaceMode: 'filesystem' - a single filesystem provider, no sandbox
  • workspaceMode: 'mounts' - mount-backed workspace for sandbox-visible cloud storage

filesystem and mounts are mutually exclusive. Use mounts when the sandbox must see cloud storage paths directly.

Sandbox is off by default. In local mode, set sandboxEnabled: true to attach a LocalSandbox whose workingDirectory matches the LocalFilesystem basePath. You can also pass a custom sandbox or tune local sandbox settings via localSandboxOptions.

Mount-backed example for cloud storage visible inside the sandbox:

import { LocalSandbox } from '@mastra/core/workspace';

createPresetWorkspace({
  workspaceMode: 'mounts',
  mounts: { '/data': myCloudFilesystem },
  sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
});

Persistence and resume

The server integration uses two Mastra storage layers:

  • Mastra's harness domain stores one scoped session record containing tenant/owner/resource identity, the active thread, mode/model, configuration, lifecycle status, and all pending native suspensions.
  • Mastra memory/thread storage remains the source of truth for messages, threads, and AgentController state. The session record is a registry and lifecycle index, not a second message store.

The external sessionId is a client handle. The durable record ID is a versioned SHA-256 scope key over tenant, owner, resource, and external session ID, so identical browser IDs cannot collide across users or tenants. Explicit destroy deletes owned threads and soft-deletes the record with deletedAt; storage retention/pruning handles physical cleanup.

Tool approvals are intentionally not persisted: the approval gate is an in-memory parked promise that does not survive a restart, so a pending approval is resolvable only within the live process. Interactive tool suspensions (ask_user, submit_plan, request_access) are the durable, resumable primitive.

Resume flow:

  1. A request comes in with sessionId
  2. HarnessSessionManager derives the trusted scope and looks up the harness record directly
  3. A fresh HarnessSession is created on the current pod
  4. The harness is reattached to the persisted threadId and resourceId
  5. Every persisted native suspension is re-registered from the record
  6. SSE/event subscriptions attach to the new in-memory session instance

This is what makes the harness resumable across pods. Pod-local memory is not the source of truth.

Display state and SSE events include currentRunId plus an array of pending suspensions. Each item has its own toolCallId and optional runId, so parallel human-input prompts can be rendered and resumed independently.

Mastra approvals are deliberately process-local. If a process dies while an approval is parked, the next runtime reports the session as interrupted; an old approval response cannot be replayed. Native tool suspensions are the durable human-input primitive.

While a session is running, sendMessage starts a normal run, followUp queues input behind the current run, and steer aborts the current run and redirects it. A session waiting on native input does not keep a model process alive: it can be evicted from the in-memory LRU and reconstructed when the user returns minutes or days later.

Human-in-the-loop tools

Lumif presets replace Mastra's built-in ask_user and submit_plan with host-owned versions (same tool ids) and disable those builtins via disableBuiltinTools:

  • ask_user — free-text or choice questions, including selectionMode. Coerces free-form mistakes (selectionMode without options) into a real free-text suspend instead of Mastra's soft failure
  • submit_plan — plan review and approval in plan mode
  • request_access — sandbox directory access prompts (only when includeRequestAccess: true and the workspace exposes a LocalFilesystem)

All interactive flows suspend via Mastra's tool suspension API instead of ad-hoc harness events. Presets keep autoResumeSuspendedTools off so the host (Studio / API respondToToolSuspension) owns resumes — Mastra's auto-resume path otherwise coaches the model to stuff resumeData into tool-call arguments. Lumif keeps the public { answer: string | string[] } response shape for ask_user and converts it to Mastra's native resume value at the server boundary.

The server disables Mastra builtins for each same-id preset tool that is registered. Turn a tool off entirely with toolToggles.ask_user = false (also disables the Mastra builtin).

Studio treats empty options and single “Use free text” proxy choices as a textarea so free-form questions still render correctly when the model mis-shapes the payload.

Server integration

Use @lumifai/harness-server with Fastify or NestJS adapters. Boot config owns workspace shape, tool packs, and permission rules:

import { createHarnessSessionManager } from '@lumifai/harness-server';
// Fastify: harnessFastifyPlugin from '@lumifai/harness-server-fastify'
// NestJS: HarnessModule from '@lumifai/harness-server-nest'

createHarnessSessionManager({
  bootConfig: {
    workspaceBasePath: './workspace',
    workspaceMode: 'local',
    sandboxEnabled: true,
    storage: new LibSQLStore({ url: 'file:/absolute/path/to/harness.db' }),
    threadLock: {
      acquire: async ({ threadId }) => {
        /* distributed lock */
      },
      release: async ({ threadId }) => {
        /* distributed unlock */
      },
    },
    toolPacks: [
      /* ... */
    ],
    permissionRules: { categories: { execute: 'ask' } },
  },
});

Built-in workspace boot options (ignored when workspace is provided):

  • workspaceMode — 'local' | 'filesystem' | 'mounts'
  • workspaceFilesystem — custom filesystem provider
  • workspaceMounts — mount map for mounts mode
  • sandboxEnabled, sandbox, localSandboxOptions
  • onMount — hook before mounting cloud filesystems into a sandbox

Adapter hooks available on the HTTP layer:

  • contextResolver(request) — derive tenancy and ownership from auth/session headers
  • authorize({ action, request, context }) — gate create/read/write/resume operations
  • allowClientResourceId — only enable for local development or trusted callers

NestJS standalone server:

import { createStandaloneHarnessNestServer } from '@lumifai/harness-server-nest';

await createStandaloneHarnessNestServer({
  port: 4310,
  bootConfig: { workspaceMode: 'local', sandboxEnabled: true },
});

Tool permissions

The server applies preset permission defaults automatically via buildHarnessOptions():

  • Read tools (workspace reads, schema inspection) → auto-approved
  • Edit / execute / other categories → prompt for approval (ask)
  • Tool pack defaults → per-tool overrides from each pack's toolConfig
  • request_access is only enabled when the workspace exposes a local filesystem, because that path is persisted via local filesystem state.

Override from server boot (recommended):

import { createHarnessSessionManager } from '@lumifai/harness-server';
import { createPostgresToolPack } from '@lumifai/harness-tool-pack-postgres';

createHarnessSessionManager({
  bootConfig: {
    toolPacks: [
      createPostgresToolPack({
        connectionString: process.env.DATABASE_URL!,
        allowedTables: ['public.campaign_briefs'],
        allowedColumns: {
          'public.campaign_briefs': ['id', 'name', 'metadata', 'tenant_id'],
        },
        jsonColumns: { 'public.campaign_briefs': ['metadata'] },
      }),
    ],
    permissionRules: {
      tools: { my_custom_tool: 'ask' },
      categories: { execute: 'deny' },
    },
  },
});

Direct harness construction:

import { createPresetPermissionConfig } from '@lumifai/harness-presets';

createLumifHarness({
  ...createPresetPermissionConfig({
    packs: [
      /* tool packs */
    ],
    overrides: { tools: { my_custom_tool: 'ask' } },
  }),
  // workspace, modes, tools, ...
});

Custom tools:

  • Add via bootConfig.extraTools (Fastify/Nest) or createPresetTools({ extra: { my_tool: createTool({...}) } })
  • Set deployment policy in bootConfig.permissionRules.tools.my_tool
  • Use requireApproval on createTool only when approval is intrinsic to the tool design
  • Optional: wrap reusable custom tools in a local ToolPack with toolConfig / permissionPolicies
  • For durable HITL, give the tool suspendSchema / resumeSchema and call suspend(); pair with a client defineSuspensionRenderer (see Browser UI)

Permissions are server-owned and are not exposed on the session HarnessConfigPatch API.

Browser UI

  • @lumifai/harness-client — framework-agnostic browser client and shared reducer/state helpers
  • @lumifai/harness-react — headless provider, hooks, browser client, session store, suspension renderer registry
  • @lumifai/harness-react-mantine — Mantine HarnessStudio components

The browser client refreshes its authoritative session snapshot after an SSE failure, and the serialized display state retains the latest run error as lastError. The Mantine studio renders concurrent pending suspensions and supports free-text, single-select, and multi-select ask_user responses.

Custom suspension UIs: pass suspensionRenderers to HarnessProvider and/or HarnessStudio. Studio merges builtins (ask_user, submit_plan, request_access) then provider then studio props (later wins by toolName). Headless apps can call useResolvedSuspensionRenderer(suspension) and resumeToolSuspension(data, toolCallId).

Presets

Import configurable presets from @lumifai/harness-presets:

  • createPresetModes() — plan and build modes
  • createPresetCustomModes() — returns the built-in modes plus your custom list when you need the final array yourself
  • createPresetSubagents() — explore subagent; opt-in websearch subagent via includeWebSearch: true
  • createPresetTools() — Lumif baseline with ask_user and submit_plan (displaces Mastra builtins). Pass packs, toolPackToggles, toolToggles, includeRequestAccess, and/or extra
  • createPresetSkills() — default .agents/skills resolver paths
  • createPresetHarnessConfig() — combines the above and merges enabled pack skill paths
  • createPresetPermissionConfig() — default category resolver and merged permissionRules for harness init

Tool packs

Import opt-in capability bundles from @lumifai/harness-tool-pack-* packages. Shared types and merge helpers live in @lumifai/harness-tool-packs:

  • ToolPack — named bundle of related tools (and optional skills) that flattens into tools at harness init
  • createPostgresToolPack() — PostgreSQL schema inspection, query, and optional allowlisted write tools (@lumifai/harness-tool-pack-postgres)
  • createWorkspaceDataToolPack() — workspace JSON, CSV, and jq query tools (@lumifai/harness-tool-pack-workspace-data)
  • createServerlessWorkflowToolPack() — serverless runtime tool pack (@lumifai/harness-tool-pack-serverless-workflow)
  • createWebSearchToolPack() — provider-native web search with structured output (@lumifai/harness-tool-pack-web-search)
  • createFileProcessingToolPack() — PDF text extraction to /processed/ (@lumifai/harness-tool-pack-file-processing)
  • createOfficeEditingToolPack() — headless revision-checked DOCX, XLSX, PPTX, and PDF editing (@lumifai/harness-tool-pack-office-editing)

Override any preset or pack via the options objects on each factory.

Example:

import { createPresetHarnessConfig } from '@lumifai/harness-presets';
import { createPostgresToolPack } from '@lumifai/harness-tool-pack-postgres';
import { createServerlessWorkflowToolPack } from '@lumifai/harness-tool-pack-serverless-workflow';
import { createWebSearchToolPack } from '@lumifai/harness-tool-pack-web-search';
import { createFileProcessingToolPack } from '@lumifai/harness-tool-pack-file-processing';
import { createOfficeEditingToolPack } from '@lumifai/harness-tool-pack-office-editing';
import { createWorkspaceDataToolPack } from '@lumifai/harness-tool-pack-workspace-data';
import { Agent } from '@mastra/core/agent';

const presets = createPresetHarnessConfig({
  subagents: {
    includeWebSearch: true,
    webSearchProvider: 'openai',
  },
  customModes: [
    {
      id: 'review',
      name: 'Review',
      defaultModelId: 'openai/gpt-5.4-mini',
      color: '#059669',
      agent: new Agent({
        id: 'lumif-review-agent',
        name: 'Review Agent',
        instructions: 'Review the user changes and report issues.',
        model: 'openai/gpt-5.4-mini',
      }),
    },
  ],
  skills: {
    paths: ['.agents/skills'],
  },
  tools: {
    packs: [
      createWorkspaceDataToolPack(),
      createPostgresToolPack({
        connectionString: process.env.DATABASE_URL,
        allowAllRoleVisible: true,
        // or resolveAccessPolicy / resolveConnectionString for production tenants
      }),
      createServerlessWorkflowToolPack({
        runtimeHost: process.env.RUNTIME_HOST!,
        workflowNamespace: 'lumif',
        resolveAuthContext: (ctx) => ({
          accessToken: ctx.requestContext?.auth?.accessToken ?? '',
        }),
      }),
      createWebSearchToolPack({
        defaultProvider: 'openai',
      }),
      createFileProcessingToolPack(),
      createOfficeEditingToolPack(),
    ],
    toolPackToggles: {
      postgres: true,
    },
    toolToggles: {
      postgres_query: true,
    },
  },
});

Tool pack toggles

  • toolPackToggles — enable or disable an entire pack (tools and bundled skills)
  • toolToggles — enable or disable individual tools by id within enabled packs
  • toolConfig.enabledByDefault on a pack — default per-tool state before toolToggles overrides

Tool packs are published as separate @lumifai/harness-tool-pack-* packages. Their bundled skills are merged into workspace.skills automatically when the pack is enabled.