@digibear/mycelium
v1.0.0
Published
A modern MUSHcode compiler, linter, and test runner with programmatic API
Maintainers
Readme
Mycelium 🍄
A modern MUSHcode compiler, linter, and test runner built with TypeScript.
Features
- Preprocessing: Powered by
@digibear/mush-formatfor#include,@definemacros, templating, and more - Linting: Validates commands and functions against flavor-specific whitelists
- Plugin System: Extensible flavor support (TinyMUX included, PennMUSH planned)
- Docker Integration: Spin up real MUSH instances for 1:1 integration testing
- Automated Testing: Run assertions against live MUSH servers
Quick Start
# Install dependencies
npm install
# Build
npm run build
# Initialize a new project
node dist/cli.js init
# Compile your code
node dist/cli.js compile
# Full build (tsc + compile)
node dist/cli.js build
# Run tests with Docker
node dist/cli.js testCLI Commands
| Command | Description |
| ------------------ | --------------------------------------- |
| mycelium init | Generate a starter mycelium.config.js |
| mycelium compile | Compile MUSHcode source files |
| mycelium build | Run tsc then compile (full build) |
| mycelium test | Start Docker, upload code, run tests |
Command Options
# Init
mycelium init [options]
-f, --force Overwrite existing config
-t, --typescript Generate .ts config instead of .js
# Compile
mycelium compile [options]
-c, --config <path> Path to config file
-o, --output <path> Output file path
# Build
mycelium build [options]
-c, --config <path> Path to config file
-o, --output <path> Output file path
--skip-tsc Skip TypeScript compilation
# Test
mycelium test [options]
-c, --config <path> Path to config file
--skip-docker Use existing server (don't manage Docker)
--keep-alive Leave Docker running after testsConfiguration Reference
Create mycelium.config.js in your project root:
/** @type {import('./src/config/index.js').MyceliumConfig} */
export default {
// Required: MUSH flavor ('tinymux', 'pennmush', or custom)
flavor: "tinymux",
// Input files to compile
include: ["src/index.mush"],
// Output directory
outDir: "dist",
// Output filename (default: out.txt)
outFile: "output.mush",
// Custom commands for linter whitelist
customCommands: ["+mycmd", "warp"],
// Custom functions for linter whitelist
customFunctions: ["myfunc"],
// mush-format options
mform: {/* see below */},
// Linter rules
linter: {/* see below */},
// Test runner config
tests: {/* see below */},
};All Options
| Option | Type | Default | Description |
| ----------------- | ---------- | ------------ | ------------------------------------------------- |
| flavor | string | required | MUSH flavor: 'tinymux', 'pennmush', or custom |
| include | string[] | [] | Input file paths or glob patterns |
| outDir | string | '.' | Output directory for compiled files |
| outFile | string | 'out.txt' | Output filename |
| customCommands | string[] | [] | Additional commands for linter |
| customFunctions | string[] | [] | Additional functions for linter |
| mform | object | {} | mush-format compiler options |
| linter | object | {} | Linter rule configuration |
| tests | object | {} | Test runner configuration |
mform Options
Configure the underlying @digibear/mush-format compiler:
mform: {
// Include #debug blocks in output (for development builds)
debug: false,
// Wrap output in installer script with success/failure reporting
installer: false,
// Banner text at top of compiled output
banner: '// Compiled with Mycelium',
// Can also be an array:
// banner: ['// Line 1', '// Line 2'],
// Custom @define macros
defines: {
'MY_OBJECT': '#123',
'VERSION': '1.0.0'
}
}| Option | Type | Default | Description |
| ----------- | -------------------- | ------- | ------------------------------------- |
| debug | boolean | false | Include #debug { } blocks in output |
| installer | boolean | false | Wrap output in installer script |
| banner | string \| string[] | none | Header comment(s) for output |
| defines | object | {} | Custom @define macro replacements |
linter Options
Configure which lint rules are enabled:
linter: {
rules: {
'unknown-command': 'warning', // 'error', 'warning', or 'off'
'unknown-function': 'error'
}
}tests Options
Configure the test runner and Docker integration:
tests: {
// MUSH server hostname
host: 'localhost',
// MUSH server port
port: 6250,
// Admin credentials for test setup
admin: {
name: 'Wizard',
password: 'potrzebie'
}
}| Option | Type | Default | Description |
| ---------------- | -------- | ------------- | -------------------- |
| host | string | 'localhost' | MUSH server hostname |
| port | number | 6250 | MUSH server port |
| admin.name | string | 'Wizard' | Admin character name |
| admin.password | string | 'potrzebie' | Admin password |
Project Structure
mycelium/
├── src/
│ ├── cli.ts # CLI entrypoint
│ ├── commands/ # CLI command handlers
│ ├── lib/ # Utilities (logger, docker)
│ ├── parser/ # AST Parser & Tokenizer
│ ├── linter/ # Lint rules engine
│ ├── compiler/ # mush-format integration
│ ├── flavors/ # Flavor definitions (TinyMUX, etc.)
│ ├── config/ # Config loader
│ ├── net/ # MushClient (Telnet)
│ └── test/ # TestRunner
├── bin/
│ └── mycelium.js # CLI executable
├── docker/
│ └── tinymux/ # TinyMUX Dockerfile
├── dist/ # Compiled output
└── mycelium.config.js # Project configDocker
Start a TinyMUX instance:
docker-compose up -dThe container:
- Compiles TinyMUX from source
- Loads a starter database
- Exposes port 6250
Extending Flavors
Create a custom flavor in src/flavors/:
import type { MushFlavor } from "../types.js";
export const MyFlavor: MushFlavor = {
name: "myflavor",
syntax: {
functions: new Set(["add", "sub", "myfunc"]),
commands: new Set(["set", "pemit", "mycmd"]),
},
};Register it in src/index.ts:
registry.register(MyFlavor);License
MIT
