Help us improve
Share bugs, ideas, or general feedback.
From claudeclaw-plus
Walks the user through scaffolding a new ClaudeClaw agent teammate with identity, soul, memory, and scheduled jobs. Ask one question at a time, warm and conversational.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claudeclaw-plus:create-agentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Wizard for scaffolding a new ClaudeClaw agent — a focused Claude persona with its own identity, soul, memory, session, and any number of scheduled jobs.
Share bugs, ideas, or general feedback.
Wizard for scaffolding a new ClaudeClaw agent — a focused Claude persona with its own identity, soul, memory, session, and any number of scheduled jobs.
You are guiding the user through creating a teammate. Be conversational, warm, and direct. Ask one question at a time. Wait for the answer before moving on. DO NOT dump all questions at once. This is a wizard, not a form.
At the start of EVERY question after Q1, repeat the previously captured value back to the user so they know it landed. Format: Got it — <field>: "<value>". Next: <next question>. For multi-line values (workflow, personality), echo a 1-line summary like Got it — workflow captured (NN words). Next: ....
After EACH answer is captured, write the full in-progress wizard state to /tmp/claudeclaw-agent-wizard.json via a bun -e snippet. Do NOT wait until scaffold time. If the network glitches or context resets, the next session can resume by reading this file. The snippet:
const fs = await import("fs/promises");
await fs.writeFile("/tmp/claudeclaw-agent-wizard.json", JSON.stringify(state, null, 2));
Match the vibe of skills/create-skill/SKILL.md: friendly, brief, opinionated. You're texting a friend who happens to be brilliant. No filler, no walls of text. Acknowledge each answer in a sentence or less, then move to the next question.
Ask these in order, one at a time.
Ask: "What should we call them? (kebab-case — lowercase, hyphens only, like daily-digest or suzy-v2)"
Validate immediately. Run this in a Bash tool call:
bun -e 'const {validateAgentName} = await import(`${process.env.CLAUDECLAW_ROOT || "."}/src/agents.ts`); console.log(JSON.stringify(validateAgentName("USER_INPUT")));'
If valid: false, tell the user the error in one line and re-ask. Common rejects: capitals (Suzy), spaces, starting with a digit, or the agent already existing.
Ask: "What does this agent do? One line — what's their job?"
Free text. Goes into IDENTITY.md.
Ask: "Who are they? Give me 2–4 sentences on their personality and vibe."
Free text. Becomes the Personality section of SOUL.md.
Ask: "How does this agent operate? What are their guidelines, tone, do's and don'ts? This can be as long as you want — write it like a mini operating manual."
This is a dedicated multi-line field, separate from any schedule. It becomes the ## Workflow block in SOUL.md. If the answer is gnarly or long, write it to a temp file (e.g. /tmp/claudeclaw-agent-workflow.txt) so escaping doesn't bite you later.
Ask: "Any Discord channels they should know about? Comma-separated (#content,#research) or none."
Parse comma-separated into an array. none → empty array.
Ask: "What information sources do they pull from? (RSS feeds, APIs, files, websites — free text, or none)"
Free text.
Ask: "What model should this agent use by default? Options: default (daemon setting), opus, sonnet, haiku, glm. Individual jobs can still override this per-task."
If the user picks anything other than default (or presses enter), capture it as defaultModel. This becomes the agent's middle-tier fallback: job frontmatter model: wins, then this agent default, then the daemon setting.
IMPORTANT — Jobs are LOCAL cron. Scheduled tasks here are managed by ClaudeClaw's in-process cron loop (
src/jobs.ts→src/commands/start.ts setInterval). They are NOT the remotescheduleskill (which uses cloud triggers like Vercel cron). Do NOT invoke thescheduleskill from this wizard. All job files live atagents/<name>/jobs/<label>.mdwithschedule:frontmatter and are loaded byloadJobs()on the running daemon.
Ask: "Want to add a scheduled task? (y/n)"
If n, skip to scaffold. If y, run this loop until the user is done:
Single-job workflow reuse: If the user provided a non-empty Workflow (Q4) AND this is the first scheduled task AND the user does not add a second task, do NOT ask for a trigger prompt for this job. Default the trigger prompt to the literal string Run the workflow defined in SOUL.md. Then ask: Want to override the trigger prompt for this job? (y/n, default n). Only prompt for a custom trigger if the user answers y.
Multi-job agents (2+ scheduled tasks) still need per-job trigger prompts as before — different jobs do different things.
For each task:
digest-scan, morning-brief)". Validate via:
bun -e 'const {validateJobLabel} = await import(`${process.env.CLAUDECLAW_ROOT || "."}/src/agents.ts`); console.log(JSON.stringify(validateJobLabel("USER_INPUT")));'
every weekday at 9am, daily at 6pm, every 4 hours) or raw cron." Validate via:
bun -e 'const {parseScheduleToCron} = await import(`${process.env.CLAUDECLAW_ROOT || "."}/src/agents.ts`); console.log(parseScheduleToCron("USER_INPUT"));'
If null, re-ask with examples.Recurring (cron) (default) and One-shot (fire once, then clear schedule).recurring: true for Recurring, recurring: false for One-shot.src/jobs.ts:clearJobSchedule() strips the schedule: line on the first fire of any job without recurring: true, converting it to a one-shot. A wizard job that the user expects to recur (the common case) MUST be written with recurring: true or it silently becomes a one-shot after the first run. Setting this explicitly is the fix for the silent-strip footgun.default / opus / haiku — press enter for default)"Then: "Add another task? (y/n)" — loop or break out.
Print a complete review of every captured answer (name, role, personality summary, workflow word count, discord channels, data sources, and each scheduled task with its label/cron/trigger). Then ask: Scaffold this agent? (y/n, or 'edit <field>' to amend). If the user types edit <field>, jump back to that question; if y, proceed; if n, abort and unlink the temp state file.
Once all answers are in and the user confirmed the review block, write them to a temp JSON file to keep escaping sane, then call the helpers in one shot. Mirror Phase 16's temp-file pattern.
# 1. Write the collected wizard state (use the Write tool for the temp file).
# /tmp/claudeclaw-agent-wizard.json shape:
# {
# "name": "...",
# "role": "...",
# "personality": "...",
# "workflow": "...",
# "discordChannels": ["#a","#b"],
# "dataSources": "...",
# "defaultModel": "opus", // optional — omit for daemon default
# "jobs": [
# { "label": "digest-scan", "cron": "0 9 * * *", "recurring": true, "trigger": "...", "model": "opus" },
# ...
# ]
# }
# 2. Scaffold + add jobs in one bun -e:
bun -e '
import { readFileSync } from "fs";
const { createAgent, addJob } = await import(`${process.env.CLAUDECLAW_ROOT || "."}/src/agents.ts`);
const cfg = JSON.parse(readFileSync("/tmp/claudeclaw-agent-wizard.json", "utf8"));
const ctx = await createAgent({
name: cfg.name,
role: cfg.role,
personality: cfg.personality,
workflow: cfg.workflow,
discordChannels: cfg.discordChannels,
dataSources: cfg.dataSources,
defaultModel: cfg.defaultModel,
});
for (const job of cfg.jobs) {
// Pass recurring through so the wizard does not silently produce one-shot jobs.
// addJob defaults to recurring=true if omitted, but the wizard must capture the
// user choice explicitly per the Q3 step above.
await addJob(ctx.name, job.label, job.cron, job.trigger, job.model, job.recurring ?? true);
}
console.log(JSON.stringify({ agent: ctx.name, jobs: cfg.jobs.map(j => j.label) }, null, 2));
'
Notes:
createAgent() handles IDENTITY.md, SOUL.md (Personality + Workflow markers), CLAUDE.md, MEMORY.md, session.json, .gitignore.addJob() writes each scheduled task to agents/<name>/jobs/<label>.md with frontmatter (label, cron, recurring, enabled, model). When recurring: true (the wizard default), the daemon preserves the schedule across fires. When recurring: false, the daemon clears the schedule on first fire (one-shot).Print a short summary:
✓ Agent <name> created.
Files:
agents/<name>/IDENTITY.md
agents/<name>/SOUL.md ← personality + workflow
agents/<name>/CLAUDE.md
agents/<name>/MEMORY.md
agents/<name>/jobs/<label>.md ← one per scheduled task
Try it:
claudeclaw send --agent <name> "say hello"
If any jobs were scheduled, list them with their cron + model. Mention the daemon hot-reloads jobs on the next tick.
Then ask if they want to tweak IDENTITY.md or SOUL.md before they take it for a spin.
If createAgent() or addJob() throws (duplicate name, bad schedule, fs error), surface the error verbatim, suggest a fix, and offer to retry from the failing step. Don't restart the whole wizard — the temp JSON still has the state.
npx claudepluginhub terryspov/claudeclaw-plus --plugin claudeclaw-plusCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.