Skip to content

@sptflo/codex

OpenAI Codex CLI Adapter for SPTFlo V3
Self-learning multi-agent orchestration following the Agentics Foundation standard

npm versionlicenseAgentics Standard


Why @sptflo/codex?

Transform OpenAI Codex CLI into a self-improving AI development system. While Codex executes code, sptflo orchestrates, coordinates, and learns from every interaction.

Traditional CodexWith SPTFlo
Stateless executionPersistent vector memory
Single-agentMulti-agent swarms (up to 15)
Manual coordinationAutomatic orchestration
No learningSelf-learning patterns (HNSW)
One platformDual-mode (Claude Code + Codex)

Key Concept: Execution Model

┌─────────────────────────────────────────────────────────────────┐
│  SPTFLO = ORCHESTRATOR (tracks state, stores memory)       │
│  CODEX = EXECUTOR (writes code, runs commands, implements)      │
└─────────────────────────────────────────────────────────────────┘

Codex does the work. SptFlow coordinates and learns.

The Self-Learning Loop

    ┌──────────────┐
    │   SEARCH     │ ──→ Find relevant patterns from past successes
    │   memory     │
    └──────┬───────┘

    ┌──────▼───────┐
    │  COORDINATE  │ ──→ Initialize swarm, spawn specialized agents
    │   swarm      │
    └──────┬───────┘

    ┌──────▼───────┐
    │   EXECUTE    │ ──→ Codex writes code, runs commands
    │   codex      │
    └──────┬───────┘

    ┌──────▼───────┐
    │    STORE     │ ──→ Save successful patterns for future use
    │   memory     │
    └──────────────┘

Quick Start

bash
# Initialize for Codex (recommended)
npx sptflo@alpha init --codex

# Full setup with all 137+ skills
npx sptflo@alpha init --codex --full

# Dual mode (both Claude Code and Codex)
npx sptflo@alpha init --dual

That's it! The MCP server is auto-registered, skills are installed, and your project is ready for self-learning development.


Features
FeatureDescription
AGENTS.md GenerationCreates project instructions for Codex
MCP IntegrationSelf-learning via memory and vector search
137+ SkillsInvoke with $skill-name syntax
Vector MemorySemantic pattern search (384-dim embeddings)
Dual PlatformSupports both Claude Code and Codex
Auto-RegistrationMCP server registered during init
HNSW Search150x-12,500x faster pattern matching
Self-LearningLearn from successes, remember patterns
GPT-5.3 SupportOptimized for latest OpenAI models
Neural TrainingTrain patterns with SONA architecture

MCP Integration (Self-Learning)

Automatic Registration

When you run init --codex, the MCP server is automatically registered with Codex:

bash
# Verify MCP is registered
codex mcp list

# Expected output:
# Name         Command  Args                   Status
# sptflo  npx      sptflo mcp start  enabled

Manual Registration

If MCP is not present, add manually:

bash
codex mcp add sptflo -- npx sptflo mcp start

MCP Tools Reference

ToolPurposeWhen to Use
memory_searchSemantic vector searchBEFORE starting any task
memory_storeSave patterns with embeddingsAFTER completing successfully
swarm_initInitialize coordinationStart of complex tasks
agent_spawnRegister agent rolesMulti-agent workflows
neural_trainTrain on patternsPeriodic improvement

Tool Parameters

memory_search

json
{
  "query": "search terms",
  "namespace": "patterns",
  "limit": 5
}

memory_store

json
{
  "key": "pattern-name",
  "value": "what worked",
  "namespace": "patterns",
  "upsert": true
}

swarm_init

json
{
  "topology": "hierarchical",
  "maxAgents": 5,
  "strategy": "specialized"
}

Self-Learning Workflow

The 4-Step Pattern

1. LEARN:    memory_search(query="task keywords") → Find similar patterns
2. COORD:    swarm_init(topology="hierarchical") → Set up coordination
3. EXECUTE:  YOU write code, run commands        → Codex does real work
4. REMEMBER: memory_store(key, value, upsert=true) → Save for future

Complete Example Prompt

Build an email validator using a learning-enabled swarm.

STEP 1 - LEARN (use MCP tool):
Use tool: memory_search
  query: "validation utility function patterns"
  namespace: "patterns"
If score > 0.7, use that pattern as reference.

STEP 2 - COORDINATE (use MCP tools):
Use tool: swarm_init with topology="hierarchical", maxAgents=3
Use tool: agent_spawn with type="coder", name="validator"

STEP 3 - EXECUTE (YOU do this - DON'T STOP HERE):
Create /tmp/validator/email.js with validateEmail() function
Create /tmp/validator/test.js with test cases
Run the tests

STEP 4 - REMEMBER (use MCP tool):
Use tool: memory_store
  key: "pattern-email-validator"
  value: "Email validation: regex, returns boolean, test cases"
  namespace: "patterns"
  upsert: true

YOU execute all code. MCP tools are for learning only.

Similarity Score Guide

ScoreMeaningAction
> 0.7Strong matchUse the pattern directly
0.5 - 0.7Partial matchAdapt and modify
< 0.5Weak matchCreate new approach

Directory Structure
project/
├── AGENTS.md                    # Main project instructions (Codex format)
├── .agents/
│   ├── config.toml              # Project configuration
│   ├── skills/                  # 137+ skills
│   │   ├── swarm-orchestration/
│   │   │   └── SKILL.md
│   │   ├── memory-management/
│   │   │   └── SKILL.md
│   │   ├── smart-methodology/
│   │   │   └── SKILL.md
│   │   └── ...
│   └── README.md                # Directory documentation
├── .codex/                      # Local overrides (gitignored)
│   ├── config.toml              # Local development settings
│   └── AGENTS.override.md       # Local instruction overrides
└── .sptflo/                # Runtime data
    ├── config.yaml              # Runtime configuration
    ├── data/                    # Memory and cache
    │   └── memory.db            # SQLite with vector embeddings
    └── logs/                    # Log files

Key Files

FilePurpose
AGENTS.mdMain instructions for Codex (required)
.agents/config.tomlProject-wide configuration
.codex/config.tomlLocal overrides (gitignored)
.sptflo/data/memory.dbVector memory database

Templates

Available Templates

TemplateSkillsLearningBest For
minimal2BasicQuick prototypes
default4YesStandard projects
full137+YesFull-featured development
enterprise137+AdvancedTeam environments

Usage

bash
# Minimal (fastest init)
npx sptflo@alpha init --codex --minimal

# Default
npx sptflo@alpha init --codex

# Full (all skills)
npx sptflo@alpha init --codex --full

Template Contents

Minimal:

  • Core swarm orchestration
  • Basic memory management

Default:

  • Swarm orchestration
  • Memory management
  • SMART methodology
  • Basic coding patterns

Full:

  • All 137+ skills
  • GitHub integration
  • Security scanning
  • Performance optimization
  • SptDB vector search
  • Neural pattern training

Platform Comparison (Claude Code vs Codex)
FeatureClaude CodeOpenAI Codex
Config FileCLAUDE.mdAGENTS.md
Skills Dir.claude/skills/.agents/skills/
Skill Syntax/skill-name$skill-name
Settingssettings.jsonconfig.toml
MCPNativeVia codex mcp add
Overrides.claude.local.md.codex/config.toml

Dual Mode

Run init --dual to set up both platforms:

bash
npx sptflo@alpha init --dual

This creates:

  • CLAUDE.md for Claude Code users
  • AGENTS.md for Codex users
  • Shared .sptflo/ runtime
  • Cross-compatible skills

Skill Invocation

Syntax

In OpenAI Codex CLI, invoke skills with $ prefix:

$swarm-orchestration
$memory-management
$smart-methodology
$security-audit
$agent-coder
$agent-tester
$github-workflow
$performance-optimization

Complete Skills Table (137+ Skills)

V3 Core Skills

SkillSyntaxDescription
V3 Security Overhaul$v3-security-overhaulComplete security architecture with CVE remediation
V3 Memory Unification$v3-memory-unificationUnify 6+ memory systems into SptDB with HNSW
V3 Integration Deep$v3-integration-deepDeep agentic-flow@alpha integration (ADR-001)
V3 Performance Optimization$v3-performance-optimizationAchieve 2.49x-7.47x speedup targets
V3 Swarm Coordination$v3-swarm-coordination15-agent hierarchical mesh coordination
V3 DDD Architecture$v3-ddd-architectureDomain-Driven Design architecture
V3 Core Implementation$v3-core-implementationCore module implementation
V3 MCP Optimization$v3-mcp-optimizationMCP server optimization and transport
V3 CLI Modernization$v3-cli-modernizationCLI modernization and hooks enhancement

SptDB & Memory Skills

SkillSyntaxDescription
SptDB Advanced$sptdb-advancedAdvanced QUIC sync, distributed coordination
SptDB Memory Patterns$sptdb-memory-patternsPersistent memory patterns for AI agents
SptDB Learning$sptdb-learningAI learning plugins with SptDB
SptDB Optimization$sptdb-optimizationQuantization (4-32bit), performance tuning
SptDB Vector Search$sptdb-vector-searchSemantic vector search with HNSW
ReasoningBank SptDB$reasoningbank-sptdbReasoningBank with SptDB integration
ReasoningBank Intelligence$reasoningbank-intelligenceAdaptive learning with ReasoningBank

Swarm & Coordination Skills

SkillSyntaxDescription
Swarm Orchestration$swarm-orchestrationMulti-agent swarms with agentic-flow
Swarm Advanced$swarm-advancedAdvanced swarm patterns for research/analysis
Hive Mind Advanced$hive-mind-advancedCollective intelligence system
Stream Chain$stream-chainStream-JSON chaining for multi-agent pipelines
Worker Integration$worker-integrationBackground worker integration
Worker Benchmarks$worker-benchmarksWorker performance benchmarks

GitHub Integration Skills

SkillSyntaxDescription
GitHub Code Review$github-code-reviewAI-powered code review swarms
GitHub Project Management$github-project-managementSwarm-coordinated project management
GitHub Multi-Repo$github-multi-repoMulti-repository coordination
GitHub Release Management$github-release-managementRelease orchestration with AI swarms
GitHub Workflow Automation$github-workflow-automationGitHub Actions automation

SMART Methodology Skills (30+)

SkillSyntaxDescription
SMART Methodology$smart-methodologyFull SMART workflow orchestration
SMART Specification$smart:spec-pseudocodeCapture full project context
SMART Architecture$smart:architectSystem architecture design
SMART Coder$smart:coderClean, efficient code generation
SMART Tester$smart:testerComprehensive testing
SMART Reviewer$smart:reviewerCode review and quality
SMART Debugger$smart:debuggerRuntime bug troubleshooting
SMART Optimizer$smart:optimizerRefactor and modularize
SMART Documenter$smart:documenterDocumentation generation
SMART DevOps$smart:devopsDevOps automation
SMART Security Review$smart:security-reviewStatic/dynamic security analysis
SMART Integration$smart:integrationSystem integration
SMART MCP$smart:mcpMCP integration management

Flow Nexus Skills

SkillSyntaxDescription
Flow Nexus Neural$flow-nexus-neuralNeural network training in E2B sandboxes
Flow Nexus Platform$flow-nexus-platformPlatform management and authentication
Flow Nexus Swarm$flow-nexus-swarmCloud-based AI swarm deployment
Flow Nexus Payments$flow-nexus:paymentsCredit management and billing
Flow Nexus Challenges$flow-nexus:challengesCoding challenges and achievements
Flow Nexus Sandbox$flow-nexus:sandboxE2B sandbox management
Flow Nexus App Store$flow-nexus:app-storeApp publishing and deployment
Flow Nexus Workflow$flow-nexus:workflowEvent-driven workflow automation

Development Skills

SkillSyntaxDescription
Pair Programming$pair-programmingAI-assisted pair programming
Skill Builder$skill-builderCreate new Claude Code Skills
Verification Quality$verification-qualityTruth scoring and quality verification
Performance Analysis$performance-analysisBottleneck detection and optimization
Agentic Jujutsu$agentic-jujutsuQuantum-resistant version control
Hooks Automation$hooks-automationAutomated coordination and learning

Memory Management Skills

SkillSyntaxDescription
Memory Neural$memory:neuralNeural pattern training
Memory Usage$memory:memory-usageMemory usage analysis
Memory Search$memory:memory-searchSemantic memory search
Memory Persist$memory:memory-persistMemory persistence

Monitoring & Analysis Skills

SkillSyntaxDescription
Real-Time View$monitoring:real-time-viewReal-time monitoring
Agent Metrics$monitoring:agent-metricsAgent performance metrics
Swarm Monitor$monitoring:swarm-monitorSwarm activity monitoring
Token Usage$analysis:token-usageToken usage optimization
Performance Report$analysis:performance-reportPerformance reporting
Bottleneck Detect$analysis:bottleneck-detectBottleneck detection

Training Skills

SkillSyntaxDescription
Specialization$training:specializationAgent specialization training
Neural Patterns$training:neural-patternsNeural pattern training
Pattern Learn$training:pattern-learnPattern learning
Model Update$training:model-updateModel updates

Automation & Optimization Skills

SkillSyntaxDescription
Self-Healing$automation:self-healingSelf-healing workflows
Smart Agents$automation:smart-agentsSmart agent auto-spawning
Session Memory$automation:session-memoryCross-session memory
Cache Manage$optimization:cache-manageCache management
Parallel Execute$optimization:parallel-executeParallel task execution
Topology Optimize$optimization:topology-optimizeAutomatic topology selection

Hooks Skills (17 Hooks + 12 Workers)

SkillSyntaxDescription
Pre-Edit$hooks:pre-editContext before editing
Post-Edit$hooks:post-editRecord editing outcome
Pre-Task$hooks:pre-taskRecord task start
Post-Task$hooks:post-taskRecord task completion
Session End$hooks:session-endEnd session and persist

Dual-Mode Skills (NEW)

SkillSyntaxDescription
Dual Spawn$dual-spawnSpawn parallel Codex workers from Claude Code
Dual Coordinate$dual-coordinateCoordinate Claude Code + Codex execution
Dual Collect$dual-collectCollect results from parallel Codex instances

Custom Skills

Create custom skills in .agents/skills/:

.agents/skills/my-skill/
└── SKILL.md

SKILL.md format:

markdown
# My Custom Skill

Instructions for what this skill does...

## Usage
Invoke with `$my-skill`

Dual-Mode Integration (Claude Code + Codex)

Hybrid Execution Model

Run Claude Code for interactive development and spawn headless Codex workers for parallel background tasks:

┌─────────────────────────────────────────────────────────────────┐
│  CLAUDE CODE (interactive)  ←→  CODEX WORKERS (headless)        │
│  - Main conversation         - Parallel background execution    │
│  - Complex reasoning         - Bulk code generation            │
│  - Architecture decisions    - Test execution                   │
│  - Final integration         - File processing                  │
└─────────────────────────────────────────────────────────────────┘

Setup

bash
# Initialize dual-mode
npx sptflo@alpha init --dual

# Creates both:
# - CLAUDE.md (Claude Code configuration)
# - AGENTS.md (Codex configuration)
# - Shared .sptflo/ runtime

Spawning Parallel Codex Workers

From Claude Code, spawn headless Codex instances:

bash
# Spawn workers in parallel (each runs independently)
claude -p "Analyze src/auth/ for security issues" --session-id "task-1" &
claude -p "Write unit tests for src/api/" --session-id "task-2" &
claude -p "Optimize database queries in src/db/" --session-id "task-3" &
wait  # Wait for all to complete

Dual-Mode Skills

SkillPlatformDescription
$dual-spawnCodexSpawn parallel workers from orchestrator
$dual-coordinateBothCoordinate cross-platform execution
$dual-collectClaude CodeCollect results from Codex workers

Dual-Mode Agents

AgentTypeExecution
codex-workerWorkerHeadless background execution
codex-coordinatorCoordinatorManage parallel worker pool
dual-orchestratorOrchestratorRoute tasks to appropriate platform

Task Routing Rules

Task ComplexityPlatformReason
Simple (1-2 files)Codex HeadlessFast, parallel
Medium (3-5 files)Claude CodeNeeds context
Complex (architecture)Claude CodeReasoning required
Bulk operationsCodex WorkersParallelize
Final reviewClaude CodeIntegration

Example Workflow

1. Claude Code receives complex feature request
2. Designs architecture and creates plan
3. Spawns 4 Codex workers:
   - Worker 1: Implement data models
   - Worker 2: Create API endpoints
   - Worker 3: Write unit tests
   - Worker 4: Generate documentation
4. Workers execute in parallel (headless)
5. Claude Code collects and integrates results
6. Final review and refinement in Claude Code

Memory Sharing

Both platforms share the same .sptflo/ runtime:

.sptflo/
├── data/
│   └── memory.db      # Shared vector memory
├── config.yaml        # Shared configuration
└── sessions/          # Cross-platform sessions

Benefits

FeatureBenefit
Parallel Execution4-8x faster for bulk tasks
Cost OptimizationRoute simple tasks to cheaper workers
Context PreservationShared memory across platforms
Best of BothInteractive + batch processing
Unified LearningPatterns learned by both platforms

CLI Commands (NEW in v3.0.0-alpha.8)

The @sptflo/codex package now includes built-in dual-mode orchestration:

bash
# List available collaboration templates
npx sptflo-codex dual templates

# Run a feature development swarm
npx sptflo-codex dual run --template feature --task "Add user authentication"

# Run a security audit swarm
npx sptflo-codex dual run --template security --task "src/auth/"

# Run a refactoring swarm
npx sptflo-codex dual run --template refactor --task "src/legacy/"

# Check collaboration status
npx sptflo-codex dual status

Pre-Built Templates

TemplatePipelinePlatforms
featurearchitect → coder → tester → reviewerClaude (architect, reviewer) + Codex (coder, tester)
securityscanner → analyzer → fixerCodex (scanner, fixer) + Claude (analyzer)
refactoranalyzer → planner → refactorer → validatorClaude (analyzer, planner) + Codex (refactorer, validator)

Programmatic API

typescript
import { DualModeOrchestrator, CollaborationTemplates } from '@sptflo/codex';

// Create orchestrator
const orchestrator = new DualModeOrchestrator({
  projectPath: process.cwd(),
  maxConcurrent: 4,
  sharedNamespace: 'collaboration',
  timeout: 300000,
});

// Listen to events
orchestrator.on('worker:started', ({ id, role }) => console.log(`Started: ${role}`));
orchestrator.on('worker:completed', ({ id }) => console.log(`Completed: ${id}`));

// Run collaboration with a template
const workers = CollaborationTemplates.featureDevelopment('Add OAuth2 login');
const result = await orchestrator.runCollaboration(workers, 'Feature: OAuth2');

console.log(`Success: ${result.success}`);
console.log(`Duration: ${result.totalDuration}ms`);
console.log(`Workers: ${result.workers.length}`);

Configuration

.agents/config.toml

toml
# Model configuration
model = "gpt-5.3"

# Approval policy: "always" | "on-request" | "never"
approval_policy = "on-request"

# Sandbox mode: "read-only" | "workspace-write" | "danger-full-access"
sandbox_mode = "workspace-write"

# Web search: "off" | "cached" | "live"
web_search = "cached"

# MCP Servers
[mcp_servers.sptflo]
command = "npx"
args = ["sptflo", "mcp", "start"]
enabled = true

# Skills
[[skills]]
path = ".agents/skills/swarm-orchestration"
enabled = true

[[skills]]
path = ".agents/skills/memory-management"
enabled = true

[[skills]]
path = ".agents/skills/smart-methodology"
enabled = true

.codex/config.toml (Local Overrides)

toml
# Local development overrides (gitignored)
# These settings override .agents/config.toml

approval_policy = "never"
sandbox_mode = "danger-full-access"
web_search = "live"

# Disable MCP in local if needed
[mcp_servers.sptflo]
enabled = false

Environment Variables

bash
# Configuration paths
SPTFLO_CONFIG=./sptflo.config.json
SPTFLO_MEMORY_PATH=./.sptflo/data

# Provider keys
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...

# MCP settings
SPTFLO_MCP_PORT=3000

Vector Search Details

Specifications

PropertyValue
Embedding Dimensions384
Search AlgorithmHNSW
Speed Improvement150x-12,500x faster
Similarity Range0.0 - 1.0
StorageSQLite with vector extension
Modelall-MiniLM-L6-v2

Namespaces

NamespacePurpose
patternsSuccessful code patterns
solutionsBug fixes and solutions
tasksTask completion records
coordinationSwarm state
resultsWorker results
defaultGeneral storage

Example Searches

javascript
// Find auth patterns
memory_search({ query: "authentication JWT patterns", namespace: "patterns" })

// Find bug solutions
memory_search({ query: "null pointer fix", namespace: "solutions" })

// Find past tasks
memory_search({ query: "user profile API", namespace: "tasks" })

API Reference

CodexInitializer Class

typescript
import { CodexInitializer } from '@sptflo/codex';

class CodexInitializer {
  /**
   * Initialize a Codex project
   */
  async initialize(options: CodexInitOptions): Promise<CodexInitResult>;

  /**
   * Preview what would be created without writing files
   */
  async dryRun(options: CodexInitOptions): Promise<string[]>;
}

initializeCodexProject Function

typescript
import { initializeCodexProject } from '@sptflo/codex';

/**
 * Quick initialization helper
 */
async function initializeCodexProject(
  projectPath: string,
  options?: Partial<CodexInitOptions>
): Promise<CodexInitResult>;

Types

typescript
interface CodexInitOptions {
  /** Project directory path */
  projectPath: string;
  /** Template to use */
  template?: 'minimal' | 'default' | 'full' | 'enterprise';
  /** Specific skills to include */
  skills?: string[];
  /** Overwrite existing files */
  force?: boolean;
  /** Enable dual mode (Claude Code + Codex) */
  dual?: boolean;
}

interface CodexInitResult {
  /** Whether initialization succeeded */
  success: boolean;
  /** List of files created */
  filesCreated: string[];
  /** List of skills generated */
  skillsGenerated: string[];
  /** Whether MCP was registered */
  mcpRegistered?: boolean;
  /** Non-fatal warnings */
  warnings?: string[];
  /** Fatal errors */
  errors?: string[];
}

Programmatic Usage

typescript
import { CodexInitializer, initializeCodexProject } from '@sptflo/codex';

// Quick initialization
const result = await initializeCodexProject('/path/to/project', {
  template: 'full',
  force: true,
  dual: false,
});

console.log(`Files created: ${result.filesCreated.length}`);
console.log(`Skills: ${result.skillsGenerated.length}`);
console.log(`MCP registered: ${result.mcpRegistered}`);

// Or use the class directly
const initializer = new CodexInitializer();
const result = await initializer.initialize({
  projectPath: '/path/to/project',
  template: 'enterprise',
  skills: ['swarm-orchestration', 'memory-management', 'security-audit'],
  force: false,
  dual: true,
});

if (result.warnings?.length) {
  console.warn('Warnings:', result.warnings);
}

Migration from Claude Code

Convert CLAUDE.md to AGENTS.md

typescript
import { migrate } from '@sptflo/codex';

const result = await migrate({
  sourcePath: './CLAUDE.md',
  targetPath: './AGENTS.md',
  preserveComments: true,
  generateSkills: true,
});

console.log(`Migrated: ${result.success}`);
console.log(`Skills generated: ${result.skillsGenerated.length}`);

Manual Migration Checklist

  1. Rename config file: CLAUDE.mdAGENTS.md
  2. Move skills: .claude/skills/.agents/skills/
  3. Update syntax: /skill-name$skill-name
  4. Convert settings: settings.jsonconfig.toml
  5. Register MCP: codex mcp add sptflo -- npx sptflo mcp start

Dual Mode Alternative

Instead of migrating, use dual mode to support both:

bash
npx sptflo@alpha init --dual

This keeps both CLAUDE.md and AGENTS.md in sync.


Troubleshooting

MCP Not Working

bash
# Check if registered
codex mcp list

# Re-register
codex mcp remove sptflo
codex mcp add sptflo -- npx sptflo mcp start

# Test connection
npx sptflo mcp test

Memory Search Returns Empty

bash
# Initialize memory database
npx sptflo memory init --force

# Check if entries exist
npx sptflo memory list

# Manually add a test pattern
npx sptflo memory store --key "test" --value "test pattern" --namespace patterns

Skills Not Loading

bash
# Verify skill directory
ls -la .agents/skills/

# Check config.toml for skill registration
cat .agents/config.toml | grep skills

# Rebuild skills
npx sptflo@alpha init --codex --force

Vector Search Slow

bash
# Check HNSW index
npx sptflo memory stats

# Rebuild index
npx sptflo memory optimize --rebuild-index

PackageDescription
@sptflo/cliMain CLI (26 commands, 140+ subcommands)
sptfloUmbrella package
@sptflo/memorySptDB with HNSW vector search
@sptflo/securitySecurity module

License

MIT

Support

Released under the MIT License.