Provides coding and architectural support for Mach language projects.
Install
mkdir -p .claude/skills/mach && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17824" && unzip -o skill.zip -d .claude/skills/mach && rm skill.zipInstalls to .claude/skills/mach
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when writing, editing, or reviewing Mach (.mach) source files. Covers the full language: project/module structure, use/fwd imports and re-exports, the shadow-module pattern, all declaration forms (def, rec, uni, fun, ext fun, val/var, test), the type grammar with the ^ secret qualifier, literals, operators and casts, statements, docstring conventions, stdlib idioms (Result/Option, std.print), the comptime channel ($mach.*/$project.*/$bin.* reads, $if/$or, $each, intrinsics, comptime parameters, variadic packs), #[...] decorators, and inline assembly (asm x86_64/aarch64/riscv64).Key capabilities
- →Write Mach (.mach) source files.
- →Edit Mach source files according to language rules.
- →Review Mach source files for correctness and style.
- →Understand Mach project and module structure.
- →Implement comptime features and inline assembly.
How it works
This skill provides guidance on Mach language rules, covering syntax, module structure, declarations, and advanced features like comptime and inline assembly. It emphasizes explicit typing and adherence to specific idioms.
Inputs & outputs
When to use mach
- →Writing Mach code
- →Reviewing Mach language syntax
- →Structuring Mach modules
About this skill
Mach
Mach is a low-level, explicitly-typed language: no type inference, no garbage
collection, no hidden control flow. Files use .mach. This skill is the fast
path for authoring correct Mach; doc/language/ in the Mach repository is the
authoritative reference and wins on any disagreement.
Hard rules - get these right
- No type inference. Every binding declares its type.
val x = 42;is an error; writeval x: i64 = 42;. - No compiler-known type aliases.
bool,usize,str,charare stdlibdefs, not built-ins. Import them before use (use std.types.bool.bool;).true/falseare stdlibvals (1/0); comparisons and logical operators produceu8. - Decorators are
#[...]attributes on the line(s) above a declaration:#[symbol("main")],#[inline],#[align(64)]. The backtick form was removed in v2.4.0 and is a migration error - never emit backticks. - Variadics are comptime packs. A trailing
va: ...parameter, consumed by$each a in va. There is nova_list/va_start/va_argand the C-style bare...parameter is a removed-syntax error. - Strings are
*u8, single-line."hello"is a pointer to null-terminated bytes. No fat-pointer string type (strisdef str: *char;); no multi-line string literal - use\nescapes. - No tagged unions, no
match. A discriminated value is areccarrying a discriminator plus a payloaduni; consumers branch withif/or. This is exactly how stdlibResult[T, E]is built. - No compound assignment.
+=etc. do not exist; writex = x + 1;. fwdis bare and always public (nopub fwd).ext funis the only body-less function form.
Project and module structure
A project has a mach.toml at its root; [project] id roots every module
path. A file at src/foo/bar.mach in project id = "myproj" is the module
myproj.foo.bar. There is no this. self-prefix - always use the full
project-rooted path, including for sibling modules. A one-segment use <id>;
resolves only when that project declares a [project] module surface file
(e.g. a library glfw imported as use glfw;); std does not - always
import full std.* paths.
A file reads top-down: module docstring, use/fwd lines, declarations.
use - private import
use std.types.size; # binds module `size`; use as size.usize
use sz: std.types.size; # module under alias; use as sz.usize
use std.types.size.usize; # binds the symbol; use bare as usize
The resolver binds whatever the path ends at: a module (members reached
qualified) or a symbol (used bare). Importing a module does not pull its
members in unqualified. No splat, no use foo.{a,b} - one name per line. A
module uses every dependency it directly names, even ones reachable through
a re-export: the dependency graph is visible at the top of every file.
fwd - public re-export
fwd impl.Point; # re-export as Point
fwd Pt: impl.Point; # re-export as Pt
fwd impl.helpers; # a module path re-exports the whole module
Mirrors use grammar; always publishes.
Shadow-module pattern
A surface file foo.mach co-exists with directory foo/ holding split
implementations. The surface uses each split and fwds its public symbols;
consumers use myproj.foo; and never name the splits. Topical splits forward
everything unconditionally; multiplatform splits pick one impl per target:
$if ($mach.build.os == $mach.os.linux) {
use impl: myproj.os.linux;
}
$or ($mach.build.os == $mach.os.windows) {
use impl: myproj.os.windows;
}
$or {
$error("myproj.os: unsupported target");
}
fwd impl.page_size;
Entrypoint and output
The stdlib provides the platform _start, which calls whatever function
exports the linker symbol main. use std.runtime; is required to link it in
even though nothing references it by name:
use std.runtime;
use std.print;
#[symbol("main")]
fun main(argc: i64, argv: **u8) i64 {
print.println("hello, mach");
ret 0;
}
use std.print; binds the leaf module print (std itself is not in scope).
It exposes print/println (stdout), eprint/eprintln (stderr), and the
format family printf/printlnf/eprintf/eprintlnf - pack-variadic, with
{} holes filled in argument order plus {:x}-style specs ({:X}, {:c},
{:5}, {:<5}, {:08x}; {{/}} for literal braces). All return
Result[usize, str].
print.printlnf("built {} in {}ms", name, elapsed);
Declarations
Modifiers: pub (public surface; without it a declaration is file-private)
applies to fun, rec, uni, def, val, var; ext (C-ABI external)
applies to functions only.
def - type alias
pub def Age: i64;
pub def BinOp: fun(i64, i64) i64;
Aliases name any type; alias and underlying type are interchangeable.
rec / uni
pub rec Point { x: i64; y: i64; }
pub rec Pair[T, U] { left: T; right: U; } # generic
pub uni Number { i: i64; f: f64; } # fields overlap; size of largest
The compiler does not track which uni field is live. The sum-type idiom
(stdlib Result[T, E] verbatim):
pub rec Result[T, E] {
tag: bool;
value: uni { ok: T; err: E; };
}
Packed layout is not available; #[align(N)] raises a type's or global's
alignment.
fun
pub fun add(a: i64, b: i64) i64 { ret a + b; }
pub fun identity[T](value: T) T { ret value; } # generic; call: identity[i64](42)
pub fun load($order: u8, p: *i64) i64 { ... } # comptime value param (see Comptime)
pub fun sum(va: ...) i64 { # variadic pack (see Comptime)
var t: i64 = 0;
$each a in va { t = t + a; }
ret t;
}
Generic params [T] take types only, no constraints; monomorphized per
instantiation; call sites always supply the types explicitly.
ext fun
#[symbol("write")]
pub ext fun libc_write(fd: i64, buf: *u8, n: i64) i64;
Body-less, ends in ;, C ABI is the contract. Provide the definition at link
time (mach build . -l c, manifest libs, or an explicit .o/.a/.so).
On PE targets pin imports to their DLL with #[library("ws2_32.dll")].
val / var
val pi: f64 = 3.14159; # immutable; initializer required
var counter: i64 = 0;
var buf: [256]u8; # default-initialized to zero
Work at module top level (pub exports) and in function bodies.
test
Tests are declarations, inline next to the code they cover, in any module:
test "point: add is commutative" {
if (add(1, 2) != add(2, 1)) { ret 1; }
ret 0;
}
The label is a required string literal. Its internal format is a convention,
not an enforced standard: choose whatever names the test clearly and stays
consistent within a project. The compiler uses a fully-qualified
module.path.symbol:behavior form (e.g.
"mach.cli.cmd.doc.write_doc:summary_only") that pins each test to the exact
unit it exercises and groups cleanly under --filter; the libraries favor a
shorter "topic: behavior" (e.g. "abs: i64 min saturates"). Either reads
well. The body checks like an i32 function: ret 0 (or falling off the end)
passes, any non-zero return fails. There are no assertion builtins; return
early on a failed check. mach test collects every test in the project
(dependencies excluded unless --include-deps), builds one executable per
test, and reports per-module; --filter <pattern> narrows, --list
enumerates.
Types
Compiler-seeded primitives (the complete set): u8 u16 u32 u64,
i8 i16 i32 i64, f32 f64, and the untyped pointer ptr. SIMD vector names
(f32x4 …) are a planned design and do not resolve as types yet.
*T # pointer ?x address-of, @p dereference
[N]T [N][M]T # array val a: [4]i64 = [4]i64{1, 2, 3, 4};
fun(T1, T2) R # function pointer val op: BinOp = add; op(2, 3)
^T # secret-qualified (see below)
Pointers index like arrays: p[i] reads the i-th element (this is how str
is walked). A fun(...) type may carry a trailing ... for FFI only.
^ - the secret qualifier
^T marks data as secret for the constant-time discipline. Secrets may move
and be stored but may never reach an observable position: a branch or loop
condition, the left operand of &&/||, a memory index, or a //%
operand - each is a compile error. Public flows up to secret implicitly; the
only downgrade is the explicit strip cast x:^ (or x:^T). Any operation
with a secret operand yields a secret result; uni variants must agree on
secrecy; a secret-welded pointer (*^T) cannot be erased to ptr. Also
rejected: a secret float operand, a secret integer multiply or variable shift
(target capability permitting), and a secret passed to a variadic pack. The
weld checks are deep (a secret nested in an aggregate counts) and fail closed.
Carry the obligation through codegen with #[oblivious].
Constant-time support is an experimental preview: the guarantee is
incomplete and unaudited, with a proven secret-disclosure path still open. Read
doc/language/secrecy.md before touching crypto code, and do not write
production cryptography against it.
Literals
| Form | Example | Notes |
|---|---|---|
| Int (dec/hex/bin/oct) | 42 0xDEAD 0b1010 0o755 1_000_000 | untyped until context |
| Typed suffix | 7i64 255u8 2.5f64 | use when context doesn't constrain |
| Float | 1.5 1.5e10 | . must be followed by a digit |
| Char | 'M' | u8; escapes \n \t \r \\ \' \0 \xHH |
| String | "hi\n" | *u8, null-terminated, single-line; adds \" |
nil | nil | null address; coerces to any pointer or function type |
Untyped literals are checked against the declared type, never used to infer
it. nil with no context types as *u8; `var cb: fun(
Content truncated.
When not to use it
- →When working with languages other than Mach.
- →When type inference or garbage collection is expected.
Limitations
- →No type inference is supported.
- →No compiler-known type aliases like `bool` or `usize`.
- →No tagged unions or `match` statements.
How it compares
This skill provides authoritative guidance on Mach's strict, low-level language features, including its explicit typing and lack of type inference, which differs from more permissive languages.
Compared to similar skills
mach side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| mach (this skill) | 0 | 24d | Review | Advanced |
| software-architecture | 333 | 6mo | No flags | Intermediate |
| codex | 32 | 2mo | Review | Advanced |
| game-development | 70 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
software-architecture
davila7
Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development.
codex
Lucklyric
Invoke Codex CLI for complex coding tasks requiring high reasoning capabilities. This skill should be invoked when users explicitly mention "Codex", request complex implementation challenges, advanced reasoning, or need high-reasoning model assistance. Automatically triggers on codex-related requests and supports session continuation for iterative development.
game-development
davila7
Game development orchestrator. Routes to platform-specific skills based on project needs.
senior-fullstack
davila7
Comprehensive fullstack development skill for building complete web applications with React, Next.js, Node.js, GraphQL, and PostgreSQL. Includes project scaffolding, code quality analysis, architecture patterns, and complete tech stack guidance. Use when building new projects, analyzing code quality, implementing design patterns, or setting up development workflows.
command-name
anthropics
This skill should be used when the user asks to "create a plugin", "scaffold a plugin", "understand plugin structure", "organize plugin components", "set up plugin.json", "use ${CLAUDE_PLUGIN_ROOT}", "add commands/agents/skills/hooks", "configure auto-discovery", or needs guidance on plugin directory layout, manifest configuration, component organization, file naming conventions, or Claude Code plugin architecture best practices.
python-project-structure
wshobson
Python project organization, module architecture, and public API design. Use when setting up new projects, organizing modules, defining public interfaces with __all__, or planning directory layouts.