AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Claude Agents

skill-gaojude-claude-agents-skill-claude-agents-skill · by gaojude

Manage Claude Code background agents (the `claude agents` / FleetView list) — spawn new background jobs, list and summarize what each agent is doing, read their conversations, rename them, set their session color, and stop or delete them. Use when the user asks to spin up a background agent, check on / summarize their agents, clean up finished jobs, or change an agent's title or color.

— No reviews yet
0 installs
34 views
0.0% view→install

Install

$ agentstack add skill-gaojude-claude-agents-skill-claude-agents-skill

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ● Filesystem access Used
  • ✓ Shell / process execution No
  • ● Environment & secrets Used
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-gaojude-claude-agents-skill-claude-agents-skill)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Claude Agents? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Managing claude agents

Background agents are sessions managed by the Claude Code daemon. There are two data sources.

  1. The CLI, which is stable, so prefer it: claude agents --json lists live sessions (interactive and background) with pid, id, name, status (busy/waiting/idle), state (working/blocked/done), sessionId, cwd, and startedAt. Add --all to include completed background sessions. Works without a TTY.
  2. The files, which are the source of truth for names and cleanup: one directory per job under the jobs root. Resolve paths portably:
CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
JOBS_DIR="$CONFIG_DIR/jobs"            # $JOBS_DIR//{state.json,timeline.jsonl,tmp/}
PROJECTS_DIR="$CONFIG_DIR/projects"    # transcripts live here (see below)

Stopping a running job goes through a third channel, the daemon's control socket; see "Stop a running agent" below.

The state.json fields that matter: state (working/blocked/done, plus stopped after a daemon-level kill), name, nameSource (auto/user), detail (last user message or status line), output (final result for done jobs), sessionId, intent (original prompt), cwd, createdAt/updatedAt.

A job's full conversation transcript is not in the job dir. It lives at:

# sessionId comes from state.json or `claude agents --json`
ls "$PROJECTS_DIR"/*/"".jsonl

If the user's claude is an alias with extra flags, call the real binary via command claude ... or $(which -p claude).

Verified against Claude Code 2.1.215 (daemon control protocol 1). The file formats are internal. If a recipe stops working on a newer version, re-verify against the binary before trusting it (e.g. strings "$(readlink -f "$(command -v claude)")" | grep -i agentColor).

Spawn a new agent

cd /path/to/project && claude --bg "the task prompt"

Returns immediately; the job appears in the agents list with an auto-generated name. Useful flags: --model , --agent , --permission-mode , --add-dir . The prompt should be self-contained, since the agent starts with no context beyond it and the project.

List and summarize agents

Quick status: claude agents --json (add --all for completed). For a richer summary, read every state.json:

python3 -  [numMessages]  2 else 8
st = json.load(open(os.path.join(cfg, "jobs", job, "state.json")))

def msgs(path):
    out = []
    for line in open(path):
        try: e = json.loads(line)
        except: continue
        if e.get("type") not in ("user", "assistant") or e.get("isMeta"): continue
        c = e.get("message", {}).get("content")
        if isinstance(c, list):
            c = " ".join(b.get("text", "") for b in c if isinstance(b, dict) and b.get("type") == "text")
        if isinstance(c, str) and c.strip():
            out.append((e["type"], c.strip().replace("\n", " ")))
    return out

paths = glob.glob(os.path.join(cfg, "projects", "*", st["sessionId"] + ".jsonl"))
m = msgs(paths[0]) if paths else []
if not m:  # fallback: find the file whose user messages contain the job's intent
    intent = (st.get("intent") or "")[:80]
    for p in sorted(glob.glob(os.path.join(cfg, "projects", "*", "*.jsonl")), key=os.path.getmtime, reverse=True):
        mm = msgs(p)
        if intent and any(r == "user" and intent in t for r, t in mm):
            m, paths = mm, [p]; break

print(f"{paths[0] if paths else 'transcript not found'} ({len(m)} messages)")
for role, text in m[-n:]:
    print(f"{role:9}: {text[:200]}")
EOF

Summarize the tail; don't dump raw lines at the user. For long transcripts, delegate reading to a subagent and keep only the summary. Live sessions can also lag: a just-started job may not have flushed any user/assistant lines yet, while its state.json detail already shows the latest exchange, so check detail first for very young jobs.

Rename an agent (title)

There is no external CLI for this. Edit the job's state.json: set name to the new title and nameSource to "user" so auto-naming won't overwrite it. Use python's json (load, modify, dump) rather than sed.

Set an agent's color

The in-session command is /color . Palette: red, blue, green, yellow, purple, orange, pink, cyan; default (or reset) clears it; no argument picks randomly. Teammate sessions inside an agent team can't set their own color; their leader assigns it.

To set it for a session from outside, do what /color does internally and append one JSONL line to that session's transcript:

printf '{"type":"agent-color","agentColor":"cyan","sessionId":"%s"}\n' "$SESSION_ID" \
  >> "$PROJECTS_DIR//$SESSION_ID.jsonl"

Locate the file by globbing for the sessionId as shown above. Colors render in the prompt bar and agents view; a live session may need to restart or refresh to pick up an externally appended color.

Stop a running agent

There is no public stop subcommand, and killing the worker's OS pid (from claude agents --json) is unreliable. The daemon treats an untracked exit as a crash, and its reconciliation passes (bg adopt: adopted=N respawned=N dead=N in $CONFIG_DIR/daemon.log) can respawn the job with the same sessionId, original createdAt, and cwd, using the template/respawnFlags cached in its records. Deleting the job directory doesn't stop anything either, and claude daemon stop is far too blunt: it shuts down the whole daemon and every background session with it.

The reliable stop is the daemon's own kill operation over its control socket, the same path the agents UI uses. command claude daemon status prints the socket's directory as sock dir; on macOS and Linux it looks like /tmp/cc-daemon-/ (Windows uses named pipes instead, so this recipe is unix-only). The protocol is one JSON line per request and one JSON line back, and a protocol mismatch error names the version the server wants, so negotiate by retrying:

python3 -  [SIGTERM|SIGKILL]  2 else "SIGTERM"

def call(path, req):
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    s.settimeout(5)
    s.connect(path)
    s.sendall(json.dumps(req).encode() + b"\n")
    buf = b""
    while not buf.endswith(b"\n"):
        c = s.recv(65536)
        if not c:
            break
        buf += c
    s.close()
    return json.loads(buf)

socks = glob.glob(f"/tmp/cc-daemon-{os.getuid()}/*/control.sock")
assert socks, "no control socket found; run `claude daemon status` for the sock dir"
for sock in socks:
    r = call(sock, {"proto": 1, "op": "kill", "short": job, "signal": sig})
    if not r.get("ok") and r.get("code") == "EPROTO":
        r = call(sock, {"proto": r["serverProto"], "op": "kill", "short": job, "signal": sig})
    print(sock, "->", r)
EOF

{"ok": true, "op": "kill"} means the daemon settled the job on purpose: it logs bg settled (killed), flips the job's state.json to "state": "stopped", and will not respawn it. ENOJOB means that daemon doesn't own the job (already exited, or the wrong `` dir when several exist). This path only reaches background workers; interactive sessions have no 8-character job id, so there is no way to hit an open terminal by mistake.

Verify against daemon truth, not the job list:

grep "settled " "$CONFIG_DIR/daemon.log" | tail -1   # expect "(killed)"
ps aux | grep "" | grep -v grep               # expect no survivors

The same socket answers a read-only liveness probe, useful when the job list looks stale: {"proto": , "op": "has", "short": ""} returns "alive": true only for a running worker. A raw kill remains the fallback when the control socket is gone; after using it, expect no settled line, and check again later for a respawned worker.

Delete and clean up agents

Removing a job from the list means deleting its directory:

rm -rf "$JOBS_DIR/"

Rules:

  • Always confirm with the user before deleting, listing exactly which jobs will go.
  • Stop running jobs first with the control-socket kill above, and wait for the settled (killed) line before deleting. Deleting the directory of a live worker does nothing to the process, and the daemon rewrites state.json from its own records on the next reconciliation pass, so the job appears to come back.
  • Deleting the job dir keeps the transcript in $PROJECTS_DIR, so the session remains resumable via claude --resume . Only delete the transcript too if the user explicitly wants the conversation gone.
  • Job dirs without a state.json are stale leftovers, safe to offer for cleanup.
  • Don't touch $JOBS_DIR/pins.json (UI pin state).

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.