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

@ordinatio/settings

v1.0.3

Published

System settings, AI provider configuration, and per-user preferences for the Ordinatio platform.

Readme

@ordinatio/settings

System settings, AI provider configuration, and per-user preferences for the Ordinatio platform.

Package: @ordinatio/settings | Version: 1.0.0 | License: MIT Tests: 115 | Error codes: 25 (SETTINGS_100-401) | Zero runtime dependencies


Table of Contents

  1. Architecture Overview
  2. Installation
  3. Module Structure
  4. Core Settings
  5. AI Settings
  6. User Preferences
  7. Database Interface
  8. Prisma Schema
  9. Validation
  10. Error Registry
  11. Callbacks
  12. Domus Integration
  13. App-Layer Bridge (System 1701)
  14. Testing
  15. API Reference

Architecture Overview

┌──────────────────────────────────────────────────────┐
│  Your Application (Next.js, Express, etc.)           │
│                                                      │
│  ┌────────────────────────────────────────────────┐  │
│  │  App-Layer Bridge (optional)                   │  │
│  │  Wires callbacks for activity logging,         │  │
│  │  security events, etc.                         │  │
│  └─────────────────────┬──────────────────────────┘  │
│                        │ imports                      │
│  ┌─────────────────────▼──────────────────────────┐  │
│  │  @ordinatio/settings                           │  │
│  │                                                │  │
│  │  ┌──────────┐ ┌──────────┐ ┌───────────────┐  │  │
│  │  │ settings │ │ai-settings│ │user-preferences│  │  │
│  │  │          │ │           │ │               │  │  │
│  │  │ getSetting│ │getLLMProv.│ │getPreferences │  │  │
│  │  │ setSetting│ │getApiKey  │ │updatePrefs    │  │  │
│  │  │ getAll.. │ │getAISet.. │ │getReplyLayout │  │  │
│  │  └──────────┘ └──────────┘ └───────────────┘  │  │
│  │                                                │  │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐      │  │
│  │  │  types   │ │  errors  │ │validation│      │  │
│  │  └──────────┘ └──────────┘ └──────────┘      │  │
│  └─────────────────────┬──────────────────────────┘  │
│                        │ uses                         │
│  ┌─────────────────────▼──────────────────────────┐  │
│  │  Database (via SettingsDb / UserPreferenceDb)   │  │
│  │  Any Prisma client or compatible object         │  │
│  └────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────┘

Key design decisions:

  • No Prisma dependency. The package defines its own minimal DB interfaces (SettingsDb, UserPreferenceDb). Any object matching the interface works — Prisma, Drizzle, a test mock, anything.
  • No env var reads in core settings. All configuration is passed as function arguments. The one exception is ai-settings.ts, which falls back to process.env for API keys (standard pattern for secret management).
  • Callback injection. Mutation functions accept an optional SettingsCallbacks parameter for side effects (activity logging, event emission). The package never imports your app's logging framework.
  • Defaults built in. Every setting key has a default value. getSetting() returns the default when no DB row exists — the system works with an empty database.

Installation

With @ordinatio/domus (recommended)

npm install @ordinatio/domus
# The setup wizard will ask which modules to install

Standalone

npm install @ordinatio/settings

The package has zero runtime dependencies. zod is a peer dependency used only for validation schemas.


Module Structure

packages/ordinatio-settings/
├── src/
│   ├── index.ts              # Barrel export
│   ├── types.ts              # DB interfaces, type definitions
│   ├── settings.ts           # Core settings CRUD (10 keys)
│   ├── ai-settings.ts        # LLM provider configuration (6 providers)
│   ├── user-preferences.ts   # Per-user preferences (reply layout)
│   ├── errors.ts             # 25 error codes (SETTINGS_100-401)
│   ├── validation.ts         # Zod schemas
│   └── __tests__/
│       ├── settings.test.ts          # 27 tests
│       └── user-preferences.test.ts  # 13 tests
├── settings.prisma           # Schema fragment (2 models, 1 enum)
├── package.json
├── vitest.config.ts
└── README.md

Core Settings

The core settings module provides a key-value store backed by a SystemSettings database table.

Setting Keys

There are 10 built-in setting keys, defined in the SETTINGS_KEYS constant:

| Key | Default | Purpose | |-----|---------|---------| | admin_feed_enabled | 'true' | Show/hide admin activity feed | | llm_provider | 'claude' | Global LLM provider selection | | llm_provider_bookkeeper | '' | Override LLM for Bookkeeper agent role | | llm_provider_coo | '' | Override LLM for COO agent role | | anthropic_api_key | '' | Anthropic Claude API key | | openai_api_key | '' | OpenAI API key | | gemini_api_key | '' | Google Gemini API key | | deepseek_api_key | '' | DeepSeek API key | | mistral_api_key | '' | Mistral API key | | xai_api_key | '' | xAI Grok API key |

Functions

import { getSetting, setBooleanSetting, getAllSettings, SETTINGS_KEYS } from '@ordinatio/settings';

// Read a single setting (returns default if not in DB)
const provider = await getSetting(db, SETTINGS_KEYS.LLM_PROVIDER);
// => 'claude'

// Read a boolean setting
const feedEnabled = await getBooleanSetting(db, SETTINGS_KEYS.ADMIN_FEED_ENABLED);
// => true

// Write a setting (upsert — creates if missing, updates if exists)
await setSetting(db, SETTINGS_KEYS.LLM_PROVIDER, 'openai', 'Active LLM provider');

// Write a boolean setting (stored as 'true'/'false' string)
await setBooleanSetting(db, SETTINGS_KEYS.ADMIN_FEED_ENABLED, false);

// Get all settings as a flat object (defaults merged with DB values)
const all = await getAllSettings(db);
// => { admin_feed_enabled: 'true', llm_provider: 'claude', ... }

How defaults work

getSetting() always returns a string — never null or undefined:

  1. Check DB for a row with the given key
  2. If found, return row.value
  3. If not found, return the built-in default from DEFAULTS
  4. If no default exists, return ''

This means the system is functional with an empty SystemSettings table.


AI Settings

The AI settings module manages LLM provider configuration. It builds on top of core settings — the same SystemSettings table stores API keys and provider selections.

6 Supported Providers

| Provider ID | Display Name | Setting Key | Env Var Fallback | |-------------|-------------|-------------|------------------| | claude | Anthropic Claude | anthropic_api_key | ANTHROPIC_API_KEY | | openai | OpenAI GPT | openai_api_key | OPENAI_API_KEY | | gemini | Google Gemini | gemini_api_key | GEMINI_API_KEY | | deepseek | DeepSeek | deepseek_api_key | DEEPSEEK_API_KEY | | mistral | Mistral AI | mistral_api_key | MISTRAL_API_KEY | | grok | xAI Grok | xai_api_key | XAI_API_KEY |

API Key Resolution Priority

When resolving an API key, the system checks:

  1. DatabaseSystemSettings row with the provider's settingKey
  2. Environment variableprocess.env[envVar]
  3. Empty string — provider is unconfigured

Per-Role Provider Overrides

Each agent role can use a different LLM provider. If no override is set for a role, it falls back to the global llm_provider setting.

import { getLLMProvider, getRoleProvider, setRoleProvider } from '@ordinatio/settings';

// Global provider
const global = await getLLMProvider(db);     // => 'claude'

// Role-specific override (null = no override, use global)
const coo = await getRoleProvider(db, 'coo'); // => 'openai' or null

// Set a role override
await setRoleProvider(db, 'bookkeeper', 'gemini');

// Clear a role override (revert to global)
await setRoleProvider(db, 'bookkeeper', '');

Key Masking

API keys are masked for safe display in the UI:

import { maskApiKey } from '@ordinatio/settings';

maskApiKey('sk-ant-api03-abcdef...wxyz5678');
// => 'sk-ant...5678'

maskApiKey('short-key');   // <= 12 chars
// => '****-key'

maskApiKey('');
// => ''

AI Settings Bundle

getAISettings() returns everything the Settings UI page needs in one call:

import { getAISettings } from '@ordinatio/settings';

const settings = await getAISettings(db);
// => {
//   provider: 'claude',                    // Active global provider
//   providers: [                           // All 6 providers with status
//     { id: 'claude', name: 'Anthropic Claude', maskedKey: 'sk-ant...5678', configured: true, placeholder: 'sk-ant-api03-...' },
//     { id: 'openai', name: 'OpenAI GPT', maskedKey: '', configured: false, placeholder: 'sk-proj-...' },
//     ...
//   ],
//   roleOverrides: {                       // Per-role overrides (only set ones)
//     coo: 'openai',
//   },
// }

User Preferences

Per-user preferences stored in the UserPreference table.

Reply Layout

The only preference currently stored is replyLayout, which controls how the email reply composer opens:

| Value | Behavior | |-------|----------| | MODAL (default) | Traditional modal dialog over the email | | SPLIT_HORIZONTAL | Email on top, reply editor on bottom | | SPLIT_VERTICAL | Email on left, reply editor on right | | POPOUT | Opens reply in a new browser window |

Functions

import { getPreferences, updatePreferences, getReplyLayout } from '@ordinatio/settings';

// Get preferences (auto-creates with defaults if first access)
const prefs = await getPreferences(db, userId);
// => { id: 'clx...', userId: 'usr_123', replyLayout: 'MODAL', createdAt: ..., updatedAt: ... }

// Update preferences
await updatePreferences(db, userId, { replyLayout: 'SPLIT_HORIZONTAL' });

// Shortcut: get just the reply layout
const layout = await getReplyLayout(db, userId);
// => 'SPLIT_HORIZONTAL'

Auto-creation: getPreferences() creates a default UserPreference record the first time a user's preferences are requested. No seed data needed.


Database Interface

The package defines two minimal interfaces instead of depending on Prisma:

SettingsDb

Used by settings.ts and ai-settings.ts:

interface SettingsDb {
  systemSettings: {
    findUnique(args: {
      where: { key: string }
    }): Promise<{ key: string; value: string; description?: string | null } | null>;

    upsert(args: {
      where: { key: string };
      create: { key: string; value: string; description?: string };
      update: { value: string; description?: string };
    }): Promise<{ key: string; value: string }>;

    findMany(args?: {
      take?: number
    }): Promise<Array<{ key: string; value: string }>>;
  };
}

UserPreferenceDb

Used by user-preferences.ts:

interface UserPreferenceDb {
  userPreference: {
    findUnique(args: { where: { userId: string } }): Promise<UserPreference | null>;
    create(args: { data: { userId: string; replyLayout: ReplyLayout } }): Promise<UserPreference>;
    upsert(args: {
      where: { userId: string };
      update: { replyLayout?: ReplyLayout };
      create: { userId: string; replyLayout: ReplyLayout };
    }): Promise<UserPreference>;
  };
}

Any Prisma client with systemSettings and userPreference models will satisfy these interfaces automatically. You can also pass a plain object for testing:

const mockDb: SettingsDb = {
  systemSettings: {
    findUnique: async () => ({ key: 'llm_provider', value: 'claude' }),
    upsert: async (args) => ({ key: args.where.key, value: args.create.value }),
    findMany: async () => [],
  },
};

Prisma Schema

The settings.prisma fragment defines the database models:

model SystemSettings {
  key         String    @id          // Setting key (unique identifier)
  value       String    @db.Text     // Setting value (stored as text)
  description String?               // Human-readable description
  updatedAt   DateTime  @updatedAt   // Last modified timestamp
}

model UserPreference {
  id          String      @id @default(cuid())
  userId      String      @unique     // One preference record per user
  replyLayout ReplyLayout @default(MODAL)
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt
}

enum ReplyLayout {
  MODAL
  SPLIT_HORIZONTAL
  SPLIT_VERTICAL
  POPOUT
}

Note: SystemSettings.key is the @id — there is no separate id column. The key itself is the primary key.

When used with @ordinatio/domus, this schema fragment is automatically merged with the main schema during prisma db push.


Validation

Zod schemas for validating API request bodies:

import { SettingKeySchema, UpdateSettingSchema } from '@ordinatio/settings';

// Validate a setting key
SettingKeySchema.parse('llm_provider');          // ok
SettingKeySchema.parse('invalid_key');           // throws ZodError

// Validate an update request
UpdateSettingSchema.parse({ key: 'llm_provider', value: 'openai' });    // ok
UpdateSettingSchema.parse({ key: 'llm_provider', value: true });        // ok (coerced to 'true')
UpdateSettingSchema.parse({ key: 'llm_provider', value: 42 });          // ok (coerced to '42')

The UpdateSettingSchema accepts string | boolean | number for the value field and auto-coerces to string via .transform(String).


Error Registry

25 error codes across 4 categories, following the System 1701 Error Reference System (Rule 8):

| Code | HTTP | Severity | Description | |------|------|----------|-------------| | SETTINGS_100 | 401 | warn | Unauthenticated request to settings endpoint | | SETTINGS_101 | 500 | error | Failed to retrieve system settings from database | | SETTINGS_102 | 500 | error | Failed to update a system setting | | SETTINGS_103 | 429 | warn | Rate limit exceeded for settings update | | SETTINGS_104 | 500 | error | Failed to read individual setting by key | | SETTINGS_200 | 400 | warn | Settings update request body validation failed | | SETTINGS_201 | 400 | warn | Setting key is not in the allowed enum list | | SETTINGS_202 | 400 | warn | AI settings update validation failed | | SETTINGS_203 | 400 | warn | Invalid LLM provider ID supplied | | SETTINGS_204 | 400 | warn | Invalid boolean value for boolean setting | | SETTINGS_300 | 401 | warn | Unauthenticated request to AI settings endpoint | | SETTINGS_301 | 500 | error | Failed to retrieve AI settings | | SETTINGS_302 | 500 | error | Failed to save AI setting or clear provider cache | | SETTINGS_400 | 500 | error | Failed to retrieve user preferences | | SETTINGS_401 | 500 | error | Failed to update user preferences |

Each error entry includes file, function, httpStatus, severity, recoverable, description, and diagnosis[] (troubleshooting steps).

Usage

import { settingsError, SETTINGS_ERRORS } from '@ordinatio/settings';

try {
  const value = await getSetting(db, key);
} catch (err) {
  const { code, ref } = settingsError('SETTINGS_104');
  // code: 'SETTINGS_104'
  // ref:  'SETTINGS_104-20260307T143000'  (timestamped for log correlation)

  const meta = SETTINGS_ERRORS.SETTINGS_104;
  // meta.description: 'Failed to read individual setting by key.'
  // meta.diagnosis: ['Database error in findUnique()...', ...]

  console.error(`[${ref}] ${meta.description}`, err);
  return Response.json({ error: meta.description, ref }, { status: meta.httpStatus });
}

Callbacks

Mutation functions accept an optional SettingsCallbacks parameter. This is how the consuming application wires in side effects (activity logging, security events, analytics) without the package knowing about those systems.

interface SettingsCallbacks {
  onSettingChanged?: (key: string, value: string, userId?: string) => Promise<void>;
  onPreferenceChanged?: (userId: string, changes: Record<string, unknown>) => Promise<void>;
}

Example: Activity logging

import { setSetting, SETTINGS_KEYS } from '@ordinatio/settings';

await setSetting(db, SETTINGS_KEYS.LLM_PROVIDER, 'openai', 'Active provider', {
  onSettingChanged: async (key, value) => {
    await createActivity(db, {
      action: 'SETTING_CHANGED',
      severity: 'info',
      metadata: { key, value },
      userId: session.user.id,
    });
  },
});

When callbacks are called

| Function | Callback | When | |----------|----------|------| | setSetting() | onSettingChanged | After successful DB upsert | | setBooleanSetting() | onSettingChanged | After successful DB upsert (value is 'true' or 'false') | | setAISetting() | onSettingChanged | After successful DB upsert (via setSetting) | | setRoleProvider() | onSettingChanged | After successful DB upsert (via setAISetting) | | updatePreferences() | onPreferenceChanged | After successful DB upsert |

Read-only functions (getSetting, getBooleanSetting, getAllSettings, getAISettings, getPreferences, getReplyLayout) never invoke callbacks.


Domus Integration

When used with @ordinatio/domus, the settings module is automatically registered and wired:

import { createDomus } from '@ordinatio/domus';

const domus = await createDomus({
  databaseUrl: process.env.DATABASE_URL,
  modules: ['settings'],  // or include alongside other modules
});

// Use the pre-wired API (db is already injected)
const provider = await domus.settings.getSetting('llm_provider');
await domus.settings.setSetting('llm_provider', 'openai');
const aiSettings = await domus.settings.getAISettings();
const prefs = await domus.settings.getPreferences(userId);

DomusSettingsApi

The Domus factory exposes this interface:

interface DomusSettingsApi {
  getSetting: (key: string) => Promise<string>;
  getBooleanSetting: (key: string) => Promise<boolean>;
  setSetting: (key: string, value: string, description?: string) => Promise<void>;
  setBooleanSetting: (key: string, value: boolean, description?: string) => Promise<void>;
  getAllSettings: () => Promise<Record<string, string>>;
  getAISettings: () => Promise<unknown>;
  getPreferences: (userId: string) => Promise<unknown>;
  updatePreferences: (userId: string, data: Record<string, unknown>) => Promise<unknown>;
  raw: unknown;  // Access the raw module for advanced usage
}

Seed Data

When the Domus setup wizard runs, the settings module seeds two default rows:

| Key | Value | Description | |-----|-------|-------------| | admin_feed_enabled | true | Enable admin activity feed | | llm_provider | claude | Active LLM provider |

The seed function is idempotent — it checks systemSettings.count() and skips if rows already exist.


App-Layer Bridge (System 1701)

In System 1701, the settings module is consumed through a thin bridge at apps/web/src/services/settings/index.ts. The bridge is pure re-exports — no wrapping or callback injection needed for most functions:

// apps/web/src/services/settings/index.ts
export {
  getSetting, getBooleanSetting, setSetting, setBooleanSetting, getAllSettings, SETTINGS_KEYS,
  getLLMProvider, getRoleProvider, setRoleProvider, getApiKey, setAISetting, getAISettings,
  maskApiKey, ALL_PROVIDER_IDS, PROVIDER_CONFIG,
  getPreferences, updatePreferences, getReplyLayout,
  settingsError, SETTINGS_ERRORS,
  SettingKeySchema, UpdateSettingSchema,
} from '@ordinatio/settings';

Backward Compatibility

The old service files still exist as thin re-exports so existing imports continue to work:

| Old Import Path | Now Re-exports From | |----------------|---------------------| | @/services/settings.service | @/services/settings (bridge) | | @/services/ai-settings.service | @/services/settings (bridge) | | @/services/user-preferences.service | @/services/settings (bridge) | | @/lib/settings/errors | @ordinatio/settings (direct) | | @/lib/validation/settings.schema | @ordinatio/settings (direct) |

No consumer files needed import path changes.


Testing

# Run all 115 tests
pnpm --filter @ordinatio/settings test:run

# Watch mode
pnpm --filter @ordinatio/settings test

Test Coverage

| File | Tests | What's Covered | |------|-------|----------------| | settings.test.ts | 27 | getSetting defaults, setSetting upsert, boolean settings, getAllSettings merge, AI settings (maskApiKey, PROVIDER_CONFIG, getLLMProvider, getRoleProvider, getApiKey, getAISettings bundle), error registry (all 25 codes, timestamped refs), validation schemas | | user-preferences.test.ts | 13 | getPreferences auto-create, updatePreferences upsert, getReplyLayout, callback invocation |

Tests use mock SettingsDb / UserPreferenceDb objects — no database required.

System 1701 Integration Tests

In System 1701, additional tests verify the bridge and API routes:

# Service tests (14 settings + 12 preferences)
pnpm --filter web vitest run src/services/settings.service.test.ts
pnpm --filter web vitest run src/services/user-preferences.service.test.ts

# Mob tests (30 adversarial tests)
pnpm --filter web vitest run src/test/mob/settings/

# AI settings page component tests (8)
pnpm --filter web vitest run src/app/dashboard/settings/ai/page.test.tsx

API Reference

Core Settings

| Function | Signature | Returns | |----------|-----------|---------| | getSetting | (db: SettingsDb, key: SettingKey) => Promise<string> | Setting value or default | | getBooleanSetting | (db: SettingsDb, key: SettingKey) => Promise<boolean> | true if value is 'true' | | setSetting | (db: SettingsDb, key: SettingKey, value: string, description?: string, callbacks?: SettingsCallbacks) => Promise<void> | — | | setBooleanSetting | (db: SettingsDb, key: SettingKey, value: boolean, description?: string, callbacks?: SettingsCallbacks) => Promise<void> | — | | getAllSettings | (db: SettingsDb) => Promise<Record<string, string>> | All settings (defaults + DB) |

AI Settings

| Function | Signature | Returns | |----------|-----------|---------| | getLLMProvider | (db: SettingsDb) => Promise<string> | Provider ID (e.g., 'claude') | | getRoleProvider | (db: SettingsDb, roleId: string) => Promise<string \| null> | Override or null | | setRoleProvider | (db: SettingsDb, roleId: string, providerId: string, callbacks?: SettingsCallbacks) => Promise<void> | — | | getApiKey | (db: SettingsDb, provider: ProviderId) => Promise<string> | Raw API key or '' | | setAISetting | (db: SettingsDb, key: string, value: string, callbacks?: SettingsCallbacks) => Promise<void> | — | | getAISettings | (db: SettingsDb) => Promise<AISettings> | Full AI config for UI | | maskApiKey | (key: string) => string | Masked key (pure function) |

User Preferences

| Function | Signature | Returns | |----------|-----------|---------| | getPreferences | (db: UserPreferenceDb, userId: string) => Promise<UserPreference> | Prefs (auto-created if missing) | | updatePreferences | (db: UserPreferenceDb, userId: string, data: { replyLayout?: ReplyLayout }, callbacks?: SettingsCallbacks) => Promise<UserPreference> | Updated prefs | | getReplyLayout | (db: UserPreferenceDb, userId: string) => Promise<ReplyLayout> | Layout enum value |

Constants

| Export | Type | Description | |--------|------|-------------| | SETTINGS_KEYS | Record<string, SettingKey> | All 10 setting key constants | | ALL_PROVIDER_IDS | ProviderId[] | ['claude', 'openai', 'gemini', 'deepseek', 'mistral', 'grok'] | | PROVIDER_CONFIG | Record<ProviderId, ProviderConfig> | Static config per provider | | SETTINGS_ERRORS | Record<string, ErrorEntry> | 25 error definitions |

Types

| Type | Description | |------|-------------| | SettingsDb | Minimal DB interface for settings operations | | UserPreferenceDb | Minimal DB interface for user preferences | | SettingKey | Union of all valid setting key strings | | ReplyLayout | 'MODAL' \| 'SPLIT_HORIZONTAL' \| 'SPLIT_VERTICAL' \| 'POPOUT' | | ProviderId | 'claude' \| 'openai' \| 'gemini' \| 'deepseek' \| 'mistral' \| 'grok' | | ProviderConfig | { settingKey, envVar, name, placeholder } | | ProviderInfo | { id, name, maskedKey, configured, placeholder } | | AISettings | { provider, providers: ProviderInfo[], roleOverrides } | | UserPreference | { id, userId, replyLayout, createdAt, updatedAt } | | SettingsCallbacks | { onSettingChanged?, onPreferenceChanged? } | | SettingKeyValue | Zod inferred type from SettingKeySchema | | UpdateSettingInput | Zod inferred type from UpdateSettingSchema |


Pugil Integration

This package includes a Pugil reporter that generates Council-consumable trial_report artifacts from test results.

# Normal test run (no Pugil overhead)
pnpm --filter @ordinatio/settings test:run

# With Pugil trial report generation
PUGIL_ENABLED=true pnpm --filter @ordinatio/settings test:run

# With Council cycle integration
PUGIL_ENABLED=true PUGIL_CYCLE_ID=cycle-settings-v1 pnpm --filter @ordinatio/settings test:run
  • Config: src/pugil.config.ts — maps test files to categories (unit, integration, adversarial, chaos, concurrency)
  • Reporter: src/pugil-reporter.ts — Vitest custom reporter, writes to pugil-reports/
  • Types: PugilTestResult, PugilTestCategory from @ordinatio/core

License

MIT