AgentSkillsCN

knowledge-ams-flags-and-schemas

当您在 tmux 或子进程中实现智能体启动,构建 stream-json SDK 集成,调试智能体启动或恢复问题,或深入了解由 AMS 管理的 Claude Code 智能体的集中式日志配置时,可使用此技能。

SKILL.md
--- frontmatter
name: knowledge-ams-flags-and-schemas
description: Use this skill when implementing agent spawning in tmux or subprocess, building stream-json SDK integrations, debugging agent startup or resume issues, or understanding centralized logging configuration for Claude Code agents managed by AMS.

Knowledge: AMS Flags and Schemas for Claude Code

Overview

This skill documents the exact CLI flags and JSON schemas used by the Agent Management Server (AMS) to spawn and communicate with Claude Code agents. Use this when:

  • Implementing agent spawning in tmux or subprocess
  • Building stream-json SDK integrations
  • Debugging agent startup or resume issues
  • Understanding centralized logging configuration

Source of Truth: /Users/sotola/AgenticProjects/agent-box-v1/services/ams-tmux/


TUI Mode (Interactive)

AMS spawns Claude in TUI (Terminal User Interface) mode by default. This runs the interactive terminal interface.

Core Command

bash
claude --dangerously-skip-permissions --log-dir <log_dir>

Required Flags

FlagDescription
--dangerously-skip-permissionsBypass all permission checks (required for headless/unattended operation)
--log-dir <path>Directory for observability logs (sse_lines.jsonl)

Optional Flags

FlagDescription
--resume <session_id>Resume an existing session by UUID
--verboseEnable verbose output
--model <model>Override model (sonnet, opus, haiku)

AMS TUI Spawn Example

bash
# Full command as spawned by AMS (from claude_tmux_spawner.py)
CLAUDE_CONFIG_DIR=~/.claude \
  ~/symlinks/claude \
    --dangerously-skip-permissions \
    --log-dir ~/centralized-logs/claude

tmux Wrapper

AMS wraps the command to keep tmux sessions alive for post-mortem debugging:

bash
bash -lc 'set +e; \
  echo "[ams_tmux] start $(date -u +%Y-%m-%dT%H:%M:%SZ)"; \
  echo "[ams_tmux] cmd: <escaped_cmd>"; \
  echo "[ams_tmux] ---"; \
  <cmd>; \
  rc=$?; \
  echo "[ams_tmux] exit rc=$rc $(date -u +%Y-%m-%dT%H:%M:%SZ)"; \
  echo "[ams_tmux] keeping tmux session alive for post-mortem"; \
  while true; do sleep 3600; done'

SDK Mode (Programmatic / stream-json)

For programmatic control, Claude Code supports bidirectional JSON streaming via stdin/stdout.

Core Command

bash
claude -p \
  --input-format stream-json \
  --output-format stream-json \
  --dangerously-skip-permissions \
  --log-dir <log_dir>

Required Flags for SDK Mode

FlagDescription
-p, --printNon-interactive mode (required for SDK)
--input-format stream-jsonAccept JSON messages on stdin
--output-format stream-jsonEmit JSONL events on stdout
--dangerously-skip-permissionsBypass permission prompts
--log-dir <path>Observability log directory

Optional SDK Flags

FlagDescription
--include-partial-messagesStream content_block_delta events as they arrive
--replay-user-messagesEcho user messages back for acknowledgment
--resume <session_id>Resume an existing session
--fork-sessionCreate new SID when resuming (use with --resume)
--verboseEnable verbose logging
--no-session-persistenceDon't save session to disk (ephemeral)

Full SDK Mode Example

bash
CLAUDE_CONFIG_DIR=~/.claude \
  node ~/symlinks/claude/cli.js \
    -p \
    --resume 757cc520-4b58-4827-9132-c6982d3f8aba \
    --input-format stream-json \
    --output-format stream-json \
    --dangerously-skip-permissions \
    --log-dir /tmp/agent-test

Input Schema (stdin)

Send JSON messages to stdin, one per line (JSONL format).

User Message

json
{
  "type": "user",
  "message": {
    "role": "user",
    "content": [
      { "type": "text", "text": "Your prompt here" }
    ]
  }
}

User Message with Image

json
{
  "type": "user",
  "message": {
    "role": "user",
    "content": [
      { "type": "text", "text": "Describe this image" },
      {
        "type": "image",
        "source": {
          "type": "base64",
          "media_type": "image/png",
          "data": "<base64_encoded_image>"
        }
      }
    ]
  }
}

Interrupt Request

json
{
  "type": "control_request",
  "request": {
    "subtype": "interrupt"
  }
}

Output Event Types (stdout)

Claude emits JSONL events on stdout. Parse each line as JSON.

message_start

Signals the beginning of a new assistant response.

json
{
  "type": "message_start",
  "message": {
    "id": "msg_...",
    "type": "message",
    "role": "assistant",
    "content": [],
    "model": "claude-sonnet-4-20250514",
    "stop_reason": null
  }
}

content_block_delta

Streaming content chunks (requires --include-partial-messages).

json
{
  "type": "content_block_delta",
  "index": 0,
  "delta": {
    "type": "text_delta",
    "text": "partial text..."
  }
}

content_block_stop

Marks the end of a content block.

json
{
  "type": "content_block_stop",
  "index": 0
}

message_stop

Signals the complete end of the assistant's response.

json
{
  "type": "message_stop"
}

assistant (Complete Message)

Full assistant message (when not using partial streaming).

json
{
  "type": "assistant",
  "message": {
    "role": "assistant",
    "content": [
      { "type": "text", "text": "Full response text..." }
    ]
  }
}

tool_use

Agent is invoking a tool.

json
{
  "type": "tool_use",
  "id": "toolu_...",
  "name": "Bash",
  "input": {
    "command": "ls -la"
  }
}

tool_result

Result from a tool execution.

json
{
  "type": "tool_result",
  "tool_use_id": "toolu_...",
  "content": "command output..."
}

error

Error from the agent.

json
{
  "type": "error",
  "error": {
    "type": "invalid_request",
    "message": "Error description"
  }
}

result

Final result when conversation completes.

json
{
  "type": "result",
  "result": "Final output text..."
}

Environment Variables

Required by AMS

VariablePurposeExample
CLAUDE_CONFIG_DIRClaude's home directory for sessions/projects~/.claude or ~/.claude
AMS_TMUX_CLAUDE_BINPath to Claude CLI binary~/symlinks/claude

Optional / Debugging

VariablePurposeExample
CLAUDE_CODE_EFFORT_LEVELEffort level (0-100, affects model behavior)75
CLAUDE_CODE_REHYDRATE_DEBUG_JSONLDebug log path for resume operations/tmp/rehydrate-debug.jsonl

AMS-Specific

VariablePurposeExample
AMS_TMUX_PORTHTTP server port8041
AMS_TMUX_SUFFIXHandler ID suffix30b21
AMS_TMUX_AGENT_LOG_DIR_TEMPLATELog directory template~/centralized-logs/{provider}

Resume Sessions

Resume in TUI Mode

bash
CLAUDE_CONFIG_DIR=~/.claude \
  claude --dangerously-skip-permissions \
         --log-dir ~/centralized-logs/claude \
         --resume <session_id>

Resume in SDK Mode

bash
CLAUDE_CONFIG_DIR=~/.claude \
  claude -p \
         --input-format stream-json \
         --output-format stream-json \
         --dangerously-skip-permissions \
         --log-dir ~/centralized-logs/claude \
         --resume <session_id>

Fork on Resume (New SID)

bash
claude --resume <session_id> --fork-session

Session File Location

Sessions are stored at:

code
$CLAUDE_CONFIG_DIR/projects/<hashed_cwd>/<session_id>.jsonl

Example:

code
~/.claude/projects/-Users-sotola-myproject/757cc520-4b58-4827-9132-c6982d3f8aba.jsonl

Complete Examples

1. Spawn Managed Agent (AMS Pattern)

python
import subprocess
import os

env = os.environ.copy()
env["CLAUDE_CONFIG_DIR"] = "~/.claude"

cmd = [
    os.path.expanduser("~/symlinks/claude"),
    "--dangerously-skip-permissions",
    "--log-dir", os.path.expanduser("~/centralized-logs/claude"),
]

# Spawn in tmux session
subprocess.run([
    "tmux", "new-session", "-d", "-s", "claude-agent-001",
    f"bash -lc '{' '.join(cmd)}; while true; do sleep 3600; done'"
], env=env)

2. SDK Mode Python Client

python
import json
import subprocess
import os

cmd = [
    "node",
    os.path.expanduser("~/symlinks/claude/cli.js"),
    "-p",
    "--input-format", "stream-json",
    "--output-format", "stream-json",
    "--dangerously-skip-permissions",
    "--log-dir", "/tmp/agent-sdk"
]

env = os.environ.copy()
env["CLAUDE_CONFIG_DIR"] = "~/.claude"

proc = subprocess.Popen(
    cmd,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    env=env,
    text=True,
    bufsize=1
)

# Send a message
msg = {
    "type": "user",
    "message": {
        "role": "user",
        "content": [{"type": "text", "text": "Hello, Claude!"}]
    }
}
proc.stdin.write(json.dumps(msg) + "\n")
proc.stdin.flush()

# Read responses
for line in proc.stdout:
    event = json.loads(line)
    if event.get("type") == "message_stop":
        break
    print(event)

3. Resume with Debug Logging

bash
cd /path/to/project && \
  CLAUDE_CONFIG_DIR=~/.claude \
  CLAUDE_CODE_REHYDRATE_DEBUG_JSONL=/tmp/resume-debug.jsonl \
  claude --resume 757cc520-4b58-4827-9132-c6982d3f8aba \
         --dangerously-skip-permissions \
         --log-dir ~/centralized-logs/claude

Session Naming Convention (tmux)

AMS uses this pattern for tmux session names:

code
agent-box-{provider}-{handler_id}-sid-{session_id}-pid-{process_id}

Example:

code
agent-box-claude-019b9e3b-d32d-7550-b219-25c88e730b21-sid-abc12345-def6-7890-ghij-klmn-pid-54321

Components

PartDescription
providerclaude or codex
handler_idUUIDv7 (time-sortable) assigned by AMS
session_idClaude's internal session UUID (UUID4)
process_idOS process ID

Troubleshooting

No Response from SDK Mode

  1. Ensure -p flag is present (required for stream-json)
  2. Check stderr for errors
  3. Verify CLAUDE_CONFIG_DIR is writable
  4. Confirm session file exists (for resume)

Resume Stalls

  1. Set CLAUDE_CODE_REHYDRATE_DEBUG_JSONL to debug
  2. Check session file exists at $CLAUDE_CONFIG_DIR/projects/<hashed_cwd>/<sid>.jsonl
  3. Ensure cwd matches the original session's cwd

Session ID Not Found in Logs

  1. Wait for claude.user_prompt or claude.session_start event (not claude.warmup)
  2. Warmup emits a temporary SID - ignore it for session identity
  3. Real SID appears in session boundary events