Skip to main content

codeman

Drive Codeman, the session manager this agent is running inside, over its HTTP API: list sessions, start worker sessions, send them prompts, block until they finish (wait / wait-output / send-and-wait), read their output, and clean up; where available, message claude workers directly (Claude Code cross-session messaging). Use when asked to orchestrate or parallelize work across Codeman sessions, watch another session, or start and manage workers. Only usable inside a Codeman-managed session (CODEMAN_MUX=1); refuse to act otherwise.

Informations de source

Dépôt
Ark0N/Codeman
Dernière activité de la source
1 septembre 2026 à 00:31
Langue détectée de SKILL.md
anglais
Étoiles
742
Forks
105

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
6 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
codeman
description
Drive Codeman, the session manager this agent is running inside, over its HTTP API: list sessions, start worker sessions, send them prompts, block until they finish (wait / wait-output / send-and-wait), read their output, and clean up; where available, message claude workers directly (Claude Code cross-session messaging). Use when asked to orchestrate or parallelize work across Codeman sessions, watch another session, or start and manage workers. Only usable inside a Codeman-managed session (CODEMAN_MUX=1); refuse to act otherwise.
# Driving Codeman from inside a session You are an agent running inside a Codeman-managed terminal session. Codeman is the server that spawned you; its HTTP API can start, prompt, watch, and delete other sessions. **Read as far as your job needs and no further.** §0 is the bootstrap, run once. §1 is the whole fast path: spawn N workers, task them, collect answers. **If §1 covers your job, run it and stop there.** The sections after it are for jobs it does not cover, and reading them to be thorough is the main reason a ten-second run takes minutes. §2 is the verb table when your job is a different one. §3 and §4 are the rules; §6 is setup and credentials, which you only need when something 401s. Everything else loads on demand, and is meant to be opened at one section, not read through: the verbs in detail (the old §5) in [reference/verbs.md](reference/verbs.md), worked multi-worker flows in [reference/recipes.md](reference/recipes.md), endpoint tables and a symptom gallery in [reference/endpoints.md](reference/endpoints.md), and direct messaging to claude workers in [reference/messaging.md](reference/messaging.md). ## 0. Guard and bootstrap If `CODEMAN_MUX` is not `1`, **stop and say so**. Do not guess an API URL; a server you are not part of is not yours to drive. ⚠️ **Your shell state does not survive between tool calls.** Each Bash call starts a fresh shell, so `$API`, `$SELF`, the `CURL` array and `delete_session` are all gone by the next call, and `$$` is a different pid. **The filesystem does survive**, so write the preamble to a file once and source it afterwards, rather than re-pasting a hundred-odd lines at the top of every call (a half-re-pasted preamble used to be the single most likely way to break a run). **Codeman seeds the preamble file for you** when it spawns a claude session (server 1.18.3+), so the bootstrap is usually nothing at all: these are the two lines every later call opens with, and your first REAL call performs them anyway: ```bash . "${XDG_CACHE_HOME:-$HOME/.cache}/codeman-agent-$CODEMAN_SESSION_ID.sh" 2>/dev/null [ "${CODEMAN_PREAMBLE:-}" = 1.21.0 ] || { echo "preamble missing or stale; run the full §0 block"; exit 1; } ``` ⚠️ **Never spend a Bash call on this check alone.** §1's block opens with this same loader, so when §1 is the job, start there: the check rides the spawn call for free, and a standalone "preamble OK" call buys nothing while costing a full model turn (measured live: a lone check plus the deliberation around it added ~6 s to a 28 s two-worker run). §0 is done the moment any job call passes its opening check. Only when a call reports missing or stale, run the full block below once — and run it **verbatim**: paste it as-is, never re-type it, trim it, or "extract the parts you need". A hand-assembled preamble is the documented failure mode of this skill: one live run rebuilt it "minimally" and lost the `X-Codeman-Parent-Session` header (every worker spawned with no lineage arc in the web UI) and the fast-path functions (the spawn fell back to a serial quick-start loop plus pid polls), turning a ten-second job into a fifty-second one. If your harness directs temporary files into a scratchpad directory, that directive covers task scratch, not this file: it is a per-session cache that every later call re-sources by this exact path, so keep the path below. If you must relocate it anyway, copy the block's content byte-for-byte unchanged and source your path in every later call instead. ```bash test "${CODEMAN_MUX:-}" = 1 || { echo "Not inside a Codeman-managed session; refusing to act."; exit 1; } : "${CODEMAN_SESSION_ID:?CODEMAN_SESSION_ID not set}" "${HOME:?HOME not set}" PRE="${XDG_CACHE_HOME:-$HOME/.cache}/codeman-agent-$CODEMAN_SESSION_ID.sh" mkdir -p "$(dirname "$PRE")" # Rewrite unless the file already ends with THIS version's stamp, so a stale or a # half-written file self-heals here instead of costing you a round trip to rm it. grep -qs '^CODEMAN_PREAMBLE=1.21.0$' "$PRE" || (umask 077; cat > "$PRE" <<'PREAMBLE' # ---- Codeman agent preamble 1.21.0 (seeded by Codeman at session spawn; the SKILL.md §0 bootstrap rewrites it when missing or stale) ---- API="${CODEMAN_API_URL:?CODEMAN_API_URL not set; refusing to guess}" SELF="${CODEMAN_SESSION_ID:?CODEMAN_SESSION_ID not set}" # Credentials, cheapest first. Your session has usually INHERITED the server's # CODEMAN_PASSWORD already (§6 explains why, and what to do when it has not); # the data dir's .env is the documented fallback, the same one `codeman attach` # reads. The data dir is wherever the hook-secret file lives. Values may be # quoted or `export`-prefixed. ENV_FILE="${CODEMAN_HOOK_SECRET_FILE:+${CODEMAN_HOOK_SECRET_FILE%hook-secret}.env}" envval() { sed -n "s/^\(export \)\{0,1\}$1=//p" "$ENV_FILE" | tail -1 | sed 's/^"\(.*\)"$/\1/; s/^'\''\(.*\)'\''$/\1/'; } if [ -z "${CODEMAN_PASSWORD:-}" ] && [ -n "$ENV_FILE" ] && [ -f "$ENV_FILE" ]; then CODEMAN_USERNAME=$(envval CODEMAN_USERNAME) CODEMAN_PASSWORD=$(envval CODEMAN_PASSWORD) fi AUTH=(); [ -n "${CODEMAN_PASSWORD:-}" ] && AUTH=(-u "${CODEMAN_USERNAME:-admin}:$CODEMAN_PASSWORD") # -k: harmless on http, required on https (self-signed cert). # X-Codeman-Parent-Session: tags workers YOU spawn as your children, so the web UI can # draw the lineage. Set once here and every present and future create call carries it; # it is ignored on every other endpoint. Purely cosmetic (see §5.1) and it can never # fail a spawn, so there is no case where you would want to leave it off. CURL=(curl -sk "${AUTH[@]}" -H "X-Codeman-Parent-Session: $SELF") CID=codeman-agent-1 # FIXED literal, never "agent-$$": see below # Fail-CLOSED session delete. The DELETE lives INSIDE the guard on purpose: the older # `is_self "$SID" || curl -X DELETE ...` shape failed OPEN, because an undefined # is_self exits 127 and the `||` branch then ran the delete completely unguarded. # Undefined delete_session is "command not found", which deletes nothing. delete_session() { local id="${1:-}" [ -n "$id" ] || { echo "refusing: empty session id"; return 1; } [ "${#SELF}" -ge 8 ] || { echo "refusing: \$SELF unset or too short to prove this is not me"; return 1; } # ids appear in full AND 8-char form (Docker exports a truncated $SELF; mux names and # UI surfaces carry 8-char ids), so compare by prefix in BOTH directions. Equality or # a one-directional check each miss a real combination, and the miss deletes you. case "$id" in "$SELF"*) echo "refusing: $id is me"; return 1 ;; esac case "$SELF" in "$id"*) echo "refusing: $id is me"; return 1 ;; esac "${CURL[@]}" -X DELETE "$API/api/v1/sessions/$id" } # ---- fast path: the four verbs, already written. §1 composes them. ---- _composer_up() { # <sid> <timeoutMs> -> "true"/"false". `shift+tab` is the one token "${CURL[@]}" -G "$API/api/v1/sessions/$1/wait-output" \ --data-urlencode 'match=shift+tab' --data-urlencode 'from=buffer' \ --data-urlencode "timeout=$2" | jq -r '.data.wait.matched // false' } _dsh_up() { # <sid> <timeoutMs> -> "true"/"false". The DeepSeek Harness TUI's # composer glyph. Override with DSH_READY_MARK for a profile that draws another one. "${CURL[@]}" -G "$API/api/v1/sessions/$1/wait-output" \ --data-urlencode "match=${DSH_READY_MARK:-❯}" --data-urlencode 'from=buffer' \ --data-urlencode "timeout=$2" | jq -r '.data.wait.matched // false' } # ---- the workspace-trust dialog: READ the screen, never press Enter blind ---- # Claude Code 2.1.252 dropped the option numbers, REVERSED them, and highlights # "No, exit" by default: # Security guide # ❯ No, exit # Yes, I trust this folder # Enter to confirm . Esc to cancel # so the bare \r that answered the old layout now answers *exit* and the pane is # dead (`status 1`) seconds after the spawn -- measured on a live 2.1.252 case. # These two read the rendered pane and steer onto the trust option instead. _trust_key() { # <sid> -> "confirm" | "move" | "" (nothing safe to press) # full=1 returns the RENDERED pane; a claude pane keeps no tmux history, so that # is the current frame rather than every repaint since launch. tail -1 anyway, # because the freshest marked row is the only one still true. "${CURL[@]}" -G "$API/api/v1/sessions/$1/terminal" --data-urlencode 'full=1' \ | jq -r '.data.terminalBuffer // empty' \ | sed -e "s/$(printf '\033')\[[0-9;?]*[a-zA-Z]//g" -e "s/$(printf '\033')[()][AB0]//g" \ | tr -d ' \t' | grep -i '❯[0-9.]*\(yes,itrustthisfolder\|no,exit\)' | tail -1 \ | sed -e 's/.*[Yy]es,.*/confirm/' -e 's/.*[Nn]o,.*/move/' } _accept_trust() { # <sid> -> 0 once it has answered the dialog, 1 if it could not local sid="$1" k i=1 while [ "$i" -le 6 ]; do k=$(_trust_key "$sid") [ -n "$k" ] || return 1 # no dialog on screen, or a layout this cannot read # A SEPARATE clientId for these keys. seq is monotonic per clientId, so # spending prompt numbers here would make the next sendwait -- whose default # seq is the epoch second -- look like a stale duplicate and vanish silently. "${CURL[@]}" -X POST "$API/api/v1/sessions/$sid/input" -H 'Content-Type: application/json' \ -d "$(jq -nc --arg k "$([ "$k" = confirm ] && printf '\r' || printf '\033[B')" \ --arg c "$CID-trust-$sid" --argjson s "$i" \ '{input:$k,useMux:true,clientId:$c,seq:$s}')" >/dev/null [ "$k" = confirm ] && return 0 sleep 1; i=$((i+1)) # re-read: the arrow is CONFIRMED before Enter goes out done return 1 } # spawn_worker <caseName> [mode] -> session id on stdout, diagnostics on stderr. # quick-start AND readiness in one call, with a strict contract: NON-EMPTY stdout means # a READY worker whose end-of-turn signal can be trusted -- a claude worker in a # hook-carrying case, or a `deepseek` worker whose harness TUI drew its composer. # Anything less is rc 1 with EMPTY stdout, and the half-spawned session is deleted here # rather than handed back, because a worker that never drew its composer would eat the # task prompt with its trust dialog. There is deliberately no pid poll: wait-output # already blocks until the composer draws, and pid!=null proved startup, never readiness. spawn_worker() { local name="${1:?spawn_worker needs a case name}" mode="${2:-claude}" q sid cp r # parentSessionId doubles the CURL header, so a spawn_worker copied off the shared # curl (or a body someone rebuilt from this recipe) still carries its lineage. # deepseek: ask for the same permission posture the Run button sends, because the # harness's own default (`workspace-write`) still ASKS, and a worker that stops on # an approval row is a worker no fan-out can finish. It is not an escalation -- # claude workers already spawn with permissions skipped, and in multi-user mode the # server clamps this back to `workspace-write` for an owner without the grant. # Spawn by hand (§5.1) when you want a worker that asks. q=$("${CURL[@]}" -X POST "$API/api/v1/quick-start" -H 'Content-Type: application/json' \ -d "$(jq -nc --arg n "$name" --arg m "$mode" --arg p "$SELF" \ '{caseName:$n,mode:$m,parentSessionId:$p} + (if $m == "deepseek" then {deepSeekConfig:{permissionMode:"danger-full-access"}} else {} end)')") sid=$(jq -r 'if .success then .data.sessionId else empty end' <<<"$q") # NOT retryable in a loop: every quick-start failure code is terminal (§5.1). [ -n "$sid" ] || { jq -c '{error,errorCode}' <<<"$q" >&2; return 1; } if [ "$mode" = deepseek ]; then # The one non-claude mode with REAL end-of-turn signals: its TUI reports # idle/working/blocked to Codeman, so sendwait, until=stop and the Approvals # Inbox all work here exactly as they do for claude. No hook file to vet # (the bridge is env-injected, not a workspace file) and no trust dialog. # ⚠️ Readiness is still not optional, and NOT interchangeable with the stop # signal: the harness's boot report lands ~300ms BEFORE the composer paints # (measured 2.26s vs 2.56s after spawn), so a sendwait fired straight after # quick-start returns on that BOOT signal, reports a turn that never ran, and # strands the prompt in a pane that was not yet taking input. r=$(_dsh_up "$sid" 45000) [ "$r" = true ] || { echo "dsh worker $sid never drew a composer: no pane-capable profile, a profile whose composer is not '${DSH_READY_MARK:-❯}' (set DSH_READY_MARK), or a harness that failed to boot -- check GET /api/v1/deepseek/status. Deleted it" >&2 delete_session "$sid" >/dev/null; return 1; } printf '%s\n' "$sid"; return 0 fi [ "$mode" = claude ] || { printf '%s\n' "$sid"; return 0; } # no other mode draws a composer to wait on # The server installs hooks into every claude workspace now, so this grep normally # passes; it stays because the install is gated on a setting the operator can turn # off, remote sessions never get hooks, and a session created by an older server # still has none. No marker means sendwait would false-resolve on flapping idle, # possibly inside the user's REAL repo: refuse rather than run the job there. cp=$(jq -r '.data.casePath // empty' <<<"$q") grep -qs '/api/hook-event' "$cp/.claude/settings.local.json" || { echo "case '$name' resolved to '$cp', which has no Codeman hooks (workspaceHooksEnabled off, remote, or an older server?): turn the setting on, or work §5.1+§5.5 by hand with markers" >&2 delete_session "$sid" >/dev/null; return 1; } # Short composer wait FIRST, then the trust dialog: a case still showing the # dialog can never pass the composer wait, so acting early keeps a cold case from # paying the whole long wait before the fallback even runs (§5.2). A warm case # matches in under a second and never reaches it, and _accept_trust returns in a # blink when there is no dialog, so this costs nothing in the ordinary slow case. r=$(_composer_up "$sid" 5000) if [ "$r" != true ]; then # Codeman answers this dialog itself and normally wins the race; this is the
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub