원클릭으로
teul
Learn how to build and scaffold Zig CLIs using the Teul framework.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Learn how to build and scaffold Zig CLIs using the Teul framework.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | teul |
| description | Learn how to build and scaffold Zig CLIs using the Teul framework. |
Teul is a modern, comptime-powered CLI framework for Zig (built for 0.16+). It provides a clean, type-safe, and boilerplate-free way to build robust command-line applications through struct-based argument parsing and tree-based command routing.
When building a CLI tool with Teul, adhere to the following principles and syntax.
In Teul, each command is a Zig struct where the fields represent the command-line arguments.
--key=value).bool fields are automatically treated as flags (e.g., --verbose).const std = @import("std");
pub const MyCmd = struct {
// Required positional argument
target: []const u8,
// Optional boolean flag (can be used as --verbose)
verbose: bool = false,
// Optional integer flag (can be used as --retries=5)
retries: u32 = 3,
// The run function executes the command
pub fn run(self: @This(), init: std.process.Init) !void {
std.debug.print("Target: {s}\n", .{self.target});
if (self.verbose) {
std.debug.print("Verbose mode enabled!\n", .{});
}
}
};
Teul allows passing a shared context to your commands, preventing the need to initialize things like database connections or HTTP clients repeatedly.
The context pointer must be consistent across all commands. Your run function should take it as the second parameter instead of std.process.Init.
pub const AppContext = struct {
init: std.process.Init,
// Add your shared state here (e.g., db: DbConnection)
};
pub const DeployCmd = struct {
target: []const u8,
pub fn run(self: @This(), ctx: *AppContext) !void {
// Access allocator through ctx.init.gpa
const allocator = ctx.init.gpa;
std.debug.print("Deploying {s}\n", .{self.target});
}
};
In main.zig, assemble your commands into a tree and initialize the application.
const std = @import("std");
const teul = @import("teul");
const DeployCmd = @import("commands/deploy.zig").DeployCmd;
const AppContext = @import("commands/deploy.zig").AppContext; // From previous example
pub fn main(init: std.process.Init) !void {
const allocator = init.gpa;
// Collect arguments
var args_iter = try init.minimal.args.iterateAllocator(allocator);
defer args_iter.deinit();
var args_list: std.ArrayList([]const u8) = .empty;
defer args_list.deinit(allocator);
while (args_iter.next()) |arg| {
try args_list.append(allocator, arg);
}
// Initialize shared context
var ctx = AppContext{
.init = init,
};
// Define the command tree
const Cmd = teul.Command(*AppContext);
const root_cmd = Cmd{
.name = "my_app",
.description = "My CLI Tool",
.subcommands = &[_]Cmd{
.{
.name = "deploy",
.description = "Deploy the target",
.run_fn = Cmd.wrap(DeployCmd),
},
},
};
// Run the app
const app = teul.App(*AppContext).init(root_cmd);
try app.run(allocator, args_list.items, init, &ctx);
}
If the teul command is not found, you must download the latest release before running the init command. Do not assume the binary is already installed.
Run the following install script to fetch the latest binary and install it to ~/.local/bin:
curl -sSL https://raw.githubusercontent.com/ivanleomk/teul/main/install.sh | bash
Once installed, it will be available in ~/.local/bin/teul (ensure this directory is in your PATH).
Teul includes an init binary for easy setup. It vendors the framework directly into src/teul/, eliminating external dependencies.
teul init ./my-new-cli
cd my-new-cli
zig build run -- --help