TL;DR
Quick reference for Ninja service management.
What is Ninja?
Ninja manages services packaged as Shurikens — self-contained bundles with metadata, scripts, and configuration templates.
Quick Start
# Install Ninja
git clone https://github.com/tunafysh/ninja.git
cd ninja && cargo build --release
sudo cp target/release/shurikenctl /usr/local/bin/
# Install a service
shurikenctl install service.shuriken
# Configure and start
shurikenctl configure service-name
shurikenctl start service-nameCore Concepts
Shuriken = Service package containing:
- Metadata (name, version, platform)
- Management scripts (start/stop logic)
- Configuration templates
- Optional tools and hooks
States: Running | Idle
Directory Structure
~/.ninja/
├── shurikens/{name}/ # Installed services
│ ├── .ninja/
│ │ ├── manifest.toml # Service definition
│ │ ├── options.toml # User config
│ │ ├── config.tmpl # Template
│ │ └── manage.ns # Management script
│ └── [service files]
└── blacksmith/ # Built packagesManifest Essentials
[shuriken]
name = "my-service"
id = "com.example.service"
version = "1.0.0"
type = "daemon"
[shuriken.management]
type = "script"
script-path = "manage.ns"
[config]
config-path = "server.conf"
[logs]
log-path = "logs/service.log"Management Script
function start()
local result = proc.spawn("bin/server")
fs.write(".ninja/service.pid", tostring(result.pid))
end
function stop()
local pid = fs.read(".ninja/service.pid")
proc.kill_pid(tonumber(pid))
fs.remove(".ninja/service.pid")
endConfiguration
Template (.ninja/config.tmpl):
[server]
host = {{ host }}
port = {{ port }}
root = {{ root }}Options (.ninja/options.toml):
host = "localhost"
port = 8080Generate:
shurikenctl configure service-namePackage Format
.shuriken binary structure:
[MAGIC: "HSRZEG"]
[metadata_length: u16]
[metadata: CBOR]
[archive_length: u32]
[archive: tar.gz]
[signature: SHA-256]Common Commands
# List services
shurikenctl list
# Start/stop
shurikenctl start {name}
shurikenctl stop {name}
# Configure
shurikenctl configure {name}
# Build package
shurikenctl forge
# Run script
shurikenctl run script.ns
# Start API server
shurikenctl api --port 8080Lua API Quick Reference
-- Filesystem
fs.read(path)
fs.write(path, content)
fs.exists(path)
fs.create_dir(path)
-- Process
proc.spawn(command)
proc.kill_pid(pid)
-- Shell
shell.exec(command)
-- Environment
env.os -- "linux", "windows", "macos"
env.get(key)
-- Time
time.sleep(seconds)
time.now(format)
-- Logging
log.info(message)
log.error(message)DSL Quick Reference
# Select and manage
select myapp
start
stop
configure
# Configuration
set port 8080
toggle debug
configure {
host = "localhost"
port = 8080
}
# Scripts
execute script.nsHTTP API Endpoints
GET /api/shurikens # List all
GET /api/shurikens/states # Get states
POST /api/shurikens/{name}/start # Start
POST /api/shurikens/{name}/stop # StopPlatform Support
- Linux: x86_64, aarch64
- Windows: x86_64
- macOS: x86_64, aarch64
Key Features
✓ Cross-platform service management
✓ Script-based or native binary control
✓ Template-based configuration
✓ PID + start time verification
✓ Lua scripting with system APIs
✓ HTTP API and DSL
✓ MCP tool integration
Best Practices
- Use script management (native is deprecated)
- Provide configuration defaults in options.toml
- Use
{{ root }}for portable paths - Version semantically (e.g., 1.0.0)
- Test locally before packaging
Troubleshooting
# Service won't start
cat ~/.ninja/shurikens/{name}/.ninja/shuriken.lck
tail -f ~/.ninja/shurikens/{name}/logs/service.log
# Stale lock file (CAREFUL!)
ps aux | grep {name}
shurikenctl lockpick {name}
# Configuration issues
shurikenctl configure {name}
cat ~/.ninja/shurikens/{name}/{config-path}Learn More
- Getting Started: Quickstart
- User Guide: Dashboard
- Developer Guide: Architecture
- Reference: CLI | API
Resources
- GitHub: tunafysh/ninja
- Documentation: ninja-website
- Issues: Report bugs