mus-skill-go: AI-powered Code Generation for MUS
April 12, 2026 ยท View on GitHub
A specialized AI skill for generating high-performance MUS serialization code in Go.
Contents
- mus-skill-go: AI-powered Code Generation for MUS
Setup
Prerequisites
- Go 1.24 or later.
- An AI agent with skill support (e.g.,
Antigravity).
Installation
Clone this repository into your project's agent directory (e.g., .agents/skills):
git clone https://github.com/mus-format/mus-skill-go .agents/skills/mus-skill-go
or use skills tool with the following command:
npx skills add github.com/mus-format/mus-skill-go
Dependencies
Ensure you have the required MUS library (v0.10.0 or later) installed in your Go project:
# buffer-based
go get github.com/mus-format/mus-go@v0.10.0
# or stream-based
go get github.com/mus-format/mus-stream-go@v0.10.0
Supported Types
You can generate serializers for the defined types only, like:
type Foo struct {
num int
}
type Bar int
Usage
Prompt:
Generate MUS serializers for the types found in the <file_name>.go file.
What to Expect
The AI agent will generate the following files in your target and related packages:
mus.ai.gen.go: Contains all generated serializers, including implementation for defined types, structs, and interfaces.mus.ai.gen_test.go: Contains comprehensive unit tests for your serializers, including validation logic.
After generation, you should always verify the generated tests and run:
go test ./...
User Hints
To customize the generation process use hints.
Serializer Name
// mus:name = CustomFoo
type Foo string
The generated serializer will be named CustomFooMUS instead of FooMUS.
Serializer Path
// mus:path = github.com/user/repo/package
type Foo string
The path hint specifies the location of the type serializer.
Ignore Field
type Foo struct {
num int
// mus:ignore = true
str string
}
Ignored field will be skipped from the serialization process.
Number Encoding
// mus:numEnc = raw
type Foo int
type Bar struct {
// mus:numEnc = raw
num int
}
Raw package will be used instead of a default varint.
Interface Serializer
// mus:impls = Foo, Bar
type MyInterface interface { ... }
You should define DTMs for ALL implementation types, or for none of them (in this case DTMs will be generated automatically).
Validation
// mus:vl = ValidateFoo
type Foo int
type Bar struct {
// mus:vl = ValidateNum
num int
}
type Zoo struct {
// mus:lenVl = ValidateLength
// mus:vl = ValidateStr
str string
// mus:elemVl = ValidateElement
arr [3]int
// mus:lenVl = ValidateLength
bsl []byte
// mus:lenVl = ValidateLength
// mus:elemVl = ValidateElement
sl []int
// mus:lenVl = ValidateLength
// mus:keyVl = ValidateKey
// mus:elemVl = ValidateValue
mp map[string]int
}
Validation function should be defined like:
func Validate(T) error { ... }
Where T is the type being validated.
Serialization Modes
There are 4 built-in serialization modes that control how the AI generates code.
- Safe (Default): Optimized for safety. It does NOT use the
unsafepackage. Numbers usevarintencoding by default. - Unsafe: Optimized for maximum performance. It uses the
unsafepackage for all types, includingstringandbyte slice. - Not Unsafe: A middle ground. It uses the
unsafepackage for all types EXCEPTstring. This is often the fastest mode without the side effects of unsafe string conversions. - Custom: Allows you to define your own rules via a
.musfile.
So you can ask the AI agent to generate code, for example, in "unsafe" mode.
.mus Configuration File
For the Custom mode place a .mus file in your project. For example:
mode: custom
int: varint
uint: varint
float: unsafe
byte: raw
bool: ord
string: ord
byte_slice: ord
time: raw
time_ser: TimeUnixUTC
Hierarchy and Search Logic
The generator uses "ascending search" logic to find the appropriate .mus
configuration:
- It looks in the current directory.
- If not found, it moves up to the parent directory until it reaches the
project root (where
go.modor.gitis located). - Overriding: Specific
.musfiles in subdirectories override more general ones found further up the tree.
Supported Configuration Values
| Key | Values | Description |
|---|---|---|
mode | custom | Mode name. |
int | varint, raw, unsafe | Default package for all integer types. |
uint | varint, raw, unsafe | Default package for all unsigned integer types. |
float | varint, raw, unsafe | Default package for all float types. |
bool | ord, unsafe | Default package for bool. |
string | ord, unsafe | Default package for string. |
byte | varint, raw, unsafe | Default package for byte. |
byte_slice | ord, unsafe | Default package for []byte. |
time | raw, unsafe | Default package for time.Time. |
time_ser | TimeUnix, TimeUnixMilli, | Specific time.Time serializer from raw or unsafe. |
TimeUnixMicro, TimeUnixNano, | ||
TimeUnixUTC, TimeUnixMilliUTC, | ||
TimeUnixMicroUTC, TimeUnixNanoUTC |
Best Practices
- Default to Safe: Use the default
safemode unless you have a confirmed performance bottleneck. - Manual DTMs: For interfaces, define DTM constants yourself for better stability.
- Validator Signatures: Ensure your validator functions match the
func(T) errorsignature.