Loading...
Loading...
Design and build agent-first CLIs with HATEOAS JSON responses, context-protecting output, and self-documenting command trees. Use when creating new CLI tools, adding commands to existing CLIs (joelclaw, slog, igs), or reviewing CLI design for agent-friendliness. Triggers on 'build a CLI', 'add a command', 'CLI design', 'agent-friendly output', or any task involving command-line tool creation.
npx skill4agent add joelhooks/joelclaw cli-designjq# This is the ONLY output format
joelclaw status
# → { "ok": true, "command": "joelclaw status", "result": {...}, "next_actions": [...] }--json--humannext_actions{
"ok": true,
"command": "joelclaw send pipeline/video.download",
"result": {
"event_id": "01KHF98SKZ7RE6HC2BH8PW2HB2",
"status": "accepted"
},
"next_actions": [
{
"command": "joelclaw run 01KHF98SKZ7RE6HC2BH8PW2HB2",
"description": "Check run status for this event"
},
{
"command": "joelclaw logs --follow",
"description": "Watch worker logs in real-time"
},
{
"command": "joelclaw health",
"description": "Check system health"
}
]
}next_actions{
"ok": true,
"command": "joelclaw",
"result": {
"description": "JoelClaw — personal AI system CLI",
"health": { "server": {...}, "worker": {...} },
"commands": [
{ "name": "send", "description": "Send event to Inngest", "usage": "joelclaw send <event> -d '<json>'" },
{ "name": "status", "description": "System status", "usage": "joelclaw status" },
{ "name": "health", "description": "Health check all services", "usage": "joelclaw health" }
]
},
"next_actions": [...]
}{
"ok": true,
"command": "joelclaw logs",
"result": {
"lines": 20,
"total": 4582,
"truncated": true,
"full_output": "/var/folders/.../joelclaw-logs-abc123.log",
"entries": ["...last 20 lines..."]
},
"next_actions": [
{ "command": "joelclaw logs --tail 100", "description": "Show more log lines" }
]
}fix{
"ok": false,
"command": "joelclaw send pipeline/video.download",
"error": {
"message": "Inngest server not responding",
"code": "SERVER_UNREACHABLE"
},
"fix": "Start the Inngest server: cd ~/Code/system-bus && docker compose up -d",
"next_actions": [
{ "command": "joelclaw health", "description": "Re-check system health after fix" },
{ "command": "docker ps", "description": "Check if Docker containers are running" }
]
}{
ok: true,
command: string, // the command that was run
result: object, // command-specific payload
next_actions: Array<{
command: string, // exact command to copy-paste/run
description: string // what it does
}>
}{
ok: false,
command: string,
error: {
message: string, // what went wrong
code: string // machine-readable error code
},
fix: string, // plain-language suggested fix
next_actions: Array<{
command: string,
description: string
}>
}slog~/Code/system-bus/igs~/Code/system-bus/@effect/cliimport { Command, Options } from "@effect/cli"
import { NodeContext, NodeRuntime } from "@effect/platform-node"
const send = Command.make("send", {
event: Options.text("event"),
data: Options.optional(Options.text("data").pipe(Options.withAlias("d"))),
}, ({ event, data }) => {
// ... execute, return JSON envelope
})
const root = Command.make("joelclaw", {}, () => {
// Root: return health + command tree
}).pipe(Command.withSubcommands([send, status, health]))~/.bun/bin/bun build src/cli.ts --compile --outfile joelclaw
cp joelclaw ~/.bun/bin/Command.makenext_actionscommands| Don't | Do |
|---|---|
| Plain text output | JSON envelope |
| Tables with ANSI colors | JSON arrays |
| JSON is the only format |
| Dump 10,000 lines | Truncate + file pointer |
| |
| Undiscoverable commands | Root returns full command tree |
| Static help text | HATEOAS next_actions |
| |
| Exit code as the only error signal | Error in JSON + exit code |
| Require the agent to read --help | Root command self-documents |
sendstatushealthlogsjoelclaw memory searchjoelclaw loop start--kebab-case--max-quality--follow-d--data-f--followdomain/actionpipeline/video.downloadcontent/summarize