Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    dbmcco

    orchestrating-tmux-claudes

    dbmcco/orchestrating-tmux-claudes
    DevOps
    8
    3 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Orchestrate multiple AI instances (clauded/codex CLIs) in tmux panes. Self-discovering coordinator with mandatory verification, synchronous monitoring, and auto-approval...

    SKILL.md

    tmux AI Orchestration - Coordinator Role

    You are the COORDINATOR running in a tmux window. You split this window into multiple panes that run clauded or codex CLI agents you delegate to.

    Core principle: Every action requires running actual bash commands. You CANNOT hallucinate - you must RUN, READ, and VERIFY everything.

    tmux-beads-loops Integration (Preferred)

    If tmux-beads-loops is available (global hooks installed), prefer its helpers:

    • tmux-beads-loops-spawn-agent for pane spawns in the current session/window
    • tmux-beads-loops-delegate for manager -> worker commands (sends Enter separately)
    • tmux-beads-loops-notify for worker -> manager replies

    Alias-friendly defaults:

    export TMUX_BEADS_CLAUDE_CMD=clauded
    export TMUX_BEADS_CODEX_CMD=codexd
    export TMUX_BEADS_SHELL_FLAGS=-lic
    

    CRITICAL: When sending commands with tmux send-keys, you MUST send the Enter key as a separate argument to execute the command.

    MONITORING APPROACH: Uses Claude Haiku via claude --model haiku to intelligently analyze worker agent output and detect state changes (SUCCESS, QUESTION, FAILED, TIMEOUT). This eliminates context pollution - coordinator sees 1-line JSON summaries instead of verbose agent output.

    When to Use This Skill

    Use when:

    • You need specialized agents working on the same codebase
    • You want visual monitoring of multiple AI workers in tmux panes
    • Tasks can be parallelized across workers
    • You need auto-approval and quality gates

    Don't use when:

    • Single simple task (do it yourself)
    • Tasks < 2 minutes (overhead not worth it)
    • Need tight interactive back-and-forth with Braydon

    Coordinator Constraints

    YOU ARE BLOCKED FROM:

    • Write, Edit, NotebookEdit (implementation code)
    • Delegating without verification
    • Reporting success without capturing pane output

    YOU MUST:

    • Run tmux commands for every state check
    • Read actual output before making decisions
    • Write breadcrumbs to /tmp for state tracking
    • Wait synchronously for tasks (sleep 90)
    • Auto-approve when quality gates pass

    Phase 0: MONITOR SCRIPT INSTALLATION (ONCE PER SESSION)

    Before delegation, ensure the monitor script exists. Run this ONCE at the start of the session:

    RUN: cat > /tmp/monitor-pane.sh <<'SCRIPT'
    #!/bin/bash
    # ABOUTME: Claude Haiku-powered pane monitor - zero context pollution
    
    PANE=$1
    STATE_FILE="/tmp/pane-${PANE##*.}-state.json"
    LAST_STATE=""
    
    # Initialize
    echo '{"state":"WORKING","needs_human":false,"timestamp":'$(date +%s)'}' > "$STATE_FILE"
    
    while true; do
      OUTPUT=$(tmux capture-pane -p -t "$PANE" -S -30 2>/dev/null)
      [ $? -ne 0 ] && echo '{"state":"TERMINATED","timestamp":'$(date +%s)'}' > "$STATE_FILE" && exit 0
    
      # Fast path: still working?
      if ! echo "$OUTPUT" | tail -1 | grep -qE '(clauded>|codex>|❯)'; then
        [ "$LAST_STATE" != "WORKING" ] && echo '{"state":"WORKING","needs_human":false,"timestamp":'$(date +%s)'}' > "$STATE_FILE"
        LAST_STATE="WORKING"
        sleep 15
        continue
      fi
    
      # Agent at prompt - analyze with Claude Haiku
      ANALYSIS=$(echo "Analyze this agent output. Respond ONLY with JSON:
    {\"state\": \"SUCCESS|QUESTION|FAILED|TIMEOUT\", \"summary\": \"brief\", \"needs_human\": true|false}
    
    Rules:
    - SUCCESS: completed, tests passing, no questions
    - QUESTION: done but asking for decisions
    - FAILED: errors or test failures
    - TIMEOUT: 120 seconds timeout message
    
    Output:
    $OUTPUT" | claude --model haiku --tools "" 2>&1 | grep -o '{.*}' | head -1)
    
      STATE_TYPE=$(echo "$ANALYSIS" | jq -r '.state' 2>/dev/null || echo "UNKNOWN")
    
      if [ "$STATE_TYPE" != "$LAST_STATE" ]; then
        echo "$ANALYSIS" | jq --arg ts "$(date +%s)" '. + {timestamp: ($ts|tonumber)}' > "$STATE_FILE"
        LAST_STATE="$STATE_TYPE"
    
        # Save full output and exit on terminal states
        [ "$STATE_TYPE" != "WORKING" ] && echo "$OUTPUT" > "/tmp/pane-${PANE##*.}-output.txt" && exit 0
      fi
    
      sleep 15
    done
    SCRIPT
    
    RUN: chmod +x /tmp/monitor-pane.sh
    

    READ OUTPUT: Monitor script created.

    Phase 1: STARTUP & DISCOVERY (MANDATORY)

    When this skill is invoked, you MUST run these commands first:

    Step 1: Discover Your Context

    RUN: SESSION=$(tmux display-message -p '#S') && echo "SESSION=$SESSION"
    

    READ OUTPUT: What session are you in? (e.g., "lfw", "home")

    RUN: MY_WINDOW=$(tmux display-message -p '#I') && echo "MY_WINDOW=$MY_WINDOW"
    

    READ OUTPUT: What window number are you in? (e.g., "1")

    RUN: MY_PANE=$(tmux display-message -p '#P') && echo "MY_PANE=$MY_PANE"
    

    READ OUTPUT: What pane number are YOU in? (e.g., "0")

    RUN: PROJECT=$(pwd) && echo "PROJECT=$PROJECT"
    

    READ OUTPUT: What project directory?

    Step 2: Inventory All Panes

    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux list-panes -t $SESSION:$COORD_WINDOW -F '#{pane_index}|#{pane_active}|#{pane_current_command}'
    

    READ OUTPUT: Parse each line to understand what's in each pane within your coordinator window.

    Example output:

    0|1|clauded      → Pane 0 (active=1) running clauded (that's YOU, the coordinator)
    1|0|bash         → Pane 1 idle bash (available)
    2|0|codex        → Pane 2 running codex CLI
    

    Step 3: Write State Breadcrumb

    RUN: cat > /tmp/tmux-coord-$SESSION.txt <<EOF
    SESSION=$SESSION
    MY_WINDOW=$MY_WINDOW
    MY_PANE=$MY_PANE
    PROJECT=$PROJECT
    DISCOVERED=$(date +%s)
    
    PANES:
    0|coordinator|clauded
    1|available|bash
    2|worker|codex
    EOF
    

    OUTPUT TO BRAYDON:

    ✅ Coordinator initialized in session: $SESSION
       My pane: $MY_PANE
       Project: $PROJECT
       Available worker panes: [list pane 2, pane 3 etc]
       Idle panes: [list pane 1 etc]
    
    Ready to delegate tasks.
    

    Phase 2: DELEGATION (MANDATORY STEPS)

    When Braydon gives you a task to delegate, follow these steps:

    Step 1: Choose Best CLI for Task

    DECISION LOGIC:

    • clauded for: Complex reasoning, architecture, TDD, code review, security
    • codex for: Fast implementation, refactoring, cleanup, known patterns

    Pick an available pane running that CLI, or split the coordinator window to create one.

    Step 2: Verify Pane Status

    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux capture-pane -p -t $SESSION:$COORD_WINDOW.$TARGET_PANE | tail -3
    

    READ OUTPUT:

    • Prompt visible (❯, $, >) → Ready for task
    • Agent working/thinking → Busy, choose different pane
    • Error/crash → Need to restart agent

    Step 3: Start Agent if Needed (Idle Pane)

    If pane shows bash prompt and no agent:

    # For Claude use `clauded` - Enter is a separate argument
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE "clauded" Enter
    
    # OR for codex:
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE "codex" Enter
    
    # Wait for startup:
    RUN: sleep 3
    
    # Verify started:
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux capture-pane -p -t $SESSION:$COORD_WINDOW.$TARGET_PANE | tail -1
    

    READ OUTPUT: Should show agent prompt.

    Step 4: Send Task (CRITICAL: Always send Enter!)

    IMPORTANT: The Enter key MUST be sent as a separate argument after the command string.

    # Correct format - Enter is outside the quotes as a separate argument
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE "your task description here" Enter
    

    Example:

    # This targets whichever window you're currently in (session:window.pane) and sends Enter to execute
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.2 "implement JWT authentication in src/auth/jwt.ts with tests" Enter
    

    Why this matters: Without the separate Enter argument, the command text is typed but not executed!

    Step 5: Start Monitor (Background)

    # Start Claude Haiku monitor in background
    RUN: /tmp/monitor-pane.sh $SESSION:$COORD_WINDOW.$TARGET_PANE &
    RUN: echo $! > /tmp/monitor-$TARGET_PANE-pid.txt
    

    Step 6: Record Delegation

    RUN: echo "$(date +%s)|$TARGET_PANE|clauded|your task description|pending" >> /tmp/tmux-tasks-$SESSION.txt
    

    OUTPUT TO BRAYDON:

    ✅ Task delegated to pane $TARGET_PANE (clauded/codex):
       Task: [task summary]
       Monitor: Running (PID in /tmp/monitor-$TARGET_PANE-pid.txt)
       State: /tmp/pane-$TARGET_PANE-state.json
    

    Phase 3: MONITORING (ZERO CONTEXT POLLUTION)

    Claude Haiku monitor runs in background. You just read state files.

    Step 1: Wait Minimum Time

    RUN: echo "Waiting 60 seconds minimum..." && sleep 60
    

    Step 2: Check State (1 Line - No Context Pollution!)

    RUN: cat /tmp/pane-$TARGET_PANE-state.json
    

    READ OUTPUT: Single line JSON with state.

    Example outputs:

    {"state":"WORKING","needs_human":false,"timestamp":1234567}
    {"state":"SUCCESS","summary":"auth complete, tests passing","needs_human":false,"timestamp":1234590}
    {"state":"QUESTION","summary":"asks about cookie compatibility","needs_human":true,"timestamp":1234595}
    {"state":"FAILED","summary":"3 tests failing","needs_human":true,"timestamp":1234600}
    {"state":"TIMEOUT","summary":"hit 120s limit","needs_human":true,"timestamp":1234605}
    

    Step 3: Parse State and Decide Action

    If state = "WORKING":

    RUN: echo "Still working, waiting 30 more seconds..." && sleep 30
    RUN: cat /tmp/pane-$TARGET_PANE-state.json
    

    READ OUTPUT: Check again. Repeat until state changes or timeout.

    If state = "SUCCESS" AND needs_human = false:

    RUN: echo "$(date +%s)|$TARGET_PANE|SUCCESS" >> /tmp/tmux-tasks-$SESSION.txt
    

    → PROCEED TO PHASE 4 (Auto-Approval)

    If state = "QUESTION" OR needs_human = true:

    OUTPUT TO BRAYDON:
    ⚠️ Pane $TARGET_PANE needs your input:
       State: QUESTION
       Summary: [show summary from JSON]
       Full output: /tmp/pane-$TARGET_PANE-output.txt
    
    Options:
    1. Review output and provide guidance
    2. Reply directly to pane $TARGET_PANE
    3. Auto-approve if question is non-blocking
    

    If state = "FAILED":

    RUN: echo "$(date +%s)|$TARGET_PANE|FAILED" >> /tmp/tmux-tasks-$SESSION.txt
    
    OUTPUT TO BRAYDON:
    ❌ Task failed in pane $TARGET_PANE
       Summary: [show summary from JSON]
       Details: /tmp/pane-$TARGET_PANE-output.txt
    
    Options:
    1. Send fix task to same pane
    2. Review full output for debugging
    3. Try different approach
    

    If state = "TIMEOUT":

    OUTPUT TO BRAYDON:
    ⏱️ Task hit 120s timeout in pane $TARGET_PANE
       Summary: [show summary from JSON]
       Task needs to be broken into smaller pieces.
       Do NOT retry as-is.
    

    Context Pollution Comparison

    Old approach (manual polling):

    Coordinator context: 50-100 lines of verbose agent output per check
    3 panes × 3 checks = 450-900 lines of noise
    

    New approach (Claude Haiku monitor):

    Coordinator context: 1 line JSON per check
    3 panes × 3 checks = 9 lines total
    **98% reduction in context pollution**
    

    Phase 4: AUTO-APPROVAL (QUALITY GATES)

    When task succeeds, automatically verify and commit.

    Step 1: Run Quality Gates

    RUN: npm test 2>&1 | tail -10
    

    READ OUTPUT: Look for "passing" or "PASS"

    • Tests pass → Continue
    • Tests fail → STOP, report to Braydon
    RUN: npm run lint 2>&1 | tail -10
    

    READ OUTPUT: Look for "0 errors" or "✓"

    • Lint clean → Continue
    • Lint errors → STOP, report to Braydon
    RUN: npm run type-check 2>&1 | tail -10
    

    READ OUTPUT: Look for "0 errors" or success

    • Types clean → Continue
    • Type errors → STOP, report to Braydon

    Step 2: Auto-Commit if All Pass

    RUN: git add .
    
    RUN: git status --short
    

    READ OUTPUT: List files being committed

    RUN: git commit -m "$(cat <<'EOF'
    [Task summary]
    
    Implemented by: [clauded/codex] (Pane $TARGET_PANE)
    Completed: $(date)
    
    🤖 Generated with Claude Code Orchestration
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    EOF
    )"
    

    READ OUTPUT: Commit SHA

    RUN: echo "$(date +%s)|$TARGET_PANE|COMMITTED|$(git rev-parse --short HEAD)" >> /tmp/tmux-tasks-$SESSION.txt
    

    OUTPUT TO BRAYDON:

    ✅ Auto-approval complete for pane $TARGET_PANE:
       Tests: ✅ Passing
       Lint: ✅ Clean
       Types: ✅ Clean
       Committed: [SHA]
    
    Pane $TARGET_PANE ready for next task.
    

    If Quality Gates Fail

    OUTPUT TO BRAYDON:

    ❌ Auto-approval BLOCKED for pane $TARGET_PANE:
       Tests: [✅/❌]
       Lint: [✅/❌]
       Types: [✅/❌]
    
    [Show relevant error output]
    
    Options:
    1. Send fix task to same pane
    2. Manual review
    3. Skip commit
    

    Phase 5: CREATE WORKER PANES (ON-DEMAND)

    All orchestration happens inside the current tmux window. When you need more capacity, split the window into additional panes.

    Step 1: Check Pane Count

    RUN: tmux list-panes -t $SESSION | wc -l
    

    READ OUTPUT: Current pane count

    • ≤4 panes → plenty of room
    • 5-6 panes → still workable but tight
    • 6 panes → stop splitting; reuse or kill idle panes

    Step 2: Split for New Pane

    # Choose split direction based on layout
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && CURRENT_PANE=$(tmux display-message -p '#P') && tmux split-window -h -t $SESSION:$COORD_WINDOW.$CURRENT_PANE
    # or
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && CURRENT_PANE=$(tmux display-message -p '#P') && tmux split-window -v -t $SESSION:$COORD_WINDOW.$CURRENT_PANE
    
    RUN: NEW_PANE=$(tmux display-message -p '#P') && echo "NEW_PANE=$NEW_PANE"
    

    READ OUTPUT: tmux focuses the newly created pane; record its index.

    Step 3: Start Agent

    # Launch clauded or codex in that pane
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$NEW_PANE clauded Enter
    # OR
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$NEW_PANE codex Enter
    
    RUN: sleep 3
    
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux capture-pane -p -t $SESSION:$COORD_WINDOW.$NEW_PANE | tail -1
    

    READ OUTPUT: Should show agent prompt (clauded> or codex>).

    Step 4: Update State

    RUN: echo "$NEW_PANE|worker|clauded|available" >> /tmp/tmux-coord-$SESSION.txt
    

    OUTPUT TO BRAYDON:

    ➕ Created new pane $NEW_PANE with clauded
       Total panes in window: [count]
       Ready for delegation
    

    If Layout Overcrowded

    ⚠️ Pane grid saturated. Kill idle pane before splitting further.
    

    Options:

    1. tmux kill-pane -t <index> for idle panes
    2. Reuse existing worker pane after it finishes
    3. Create another tmux window only if Braydon approves

    Phase 6: RECOVERY (WHEN THINGS GO WRONG)

    If agent stuck, timed out, or crashed:

    Capture State

    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux capture-pane -p -S -50 -t $SESSION:$COORD_WINDOW.$TARGET_PANE > /tmp/stuck-pane-$TARGET_PANE-$(date +%s).log
    

    Kill Stuck Agent

    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE C-c
    RUN: sleep 1
    RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE clear Enter
    

    Report to Braydon

    OUTPUT TO BRAYDON:

    ⚠️ Pane $TARGET_PANE stuck/failed
       Captured: /tmp/stuck-pane-$TARGET_PANE-*.log
       Agent killed and pane cleared.
    
    Options:
    1. Re-delegate with simpler task
    2. Show captured output
    3. Use different pane
    

    Common Workflows

    Simple Feature Implementation

    1. INSTALL MONITOR: Create /tmp/monitor-pane.sh (Phase 0)
    2. STARTUP: Discover context (Phase 1)
    3. DELEGATE: Send task + start monitor (Phase 2)
       RUN: tmux send-keys -t $PANE "implement feature X with tests" Enter
       RUN: /tmp/monitor-pane.sh $PANE &
    4. MONITOR: Read state file (Phase 3)
       RUN: sleep 60
       RUN: cat /tmp/pane-2-state.json
       → {"state":"SUCCESS","needs_human":false}
    5. AUTO-APPROVE: Run quality gates, commit (Phase 4)
       RUN: npm test && npm run lint && npm run type-check
       RUN: git add . && git commit -m "..."
    

    Parallel Tasks (Zero Context Pollution!)

    1. INSTALL MONITOR (Phase 0)
    2. STARTUP (Phase 1)
    3. DELEGATE Task A to pane 2 + start monitor (Phase 2)
       RUN: tmux send-keys -t pane2 "implement auth" Enter
       RUN: /tmp/monitor-pane.sh pane2 &
    4. DELEGATE Task B to pane 3 + start monitor (Phase 2)
       RUN: tmux send-keys -t pane3 "write API docs" Enter
       RUN: /tmp/monitor-pane.sh pane3 &
    5. MONITOR both (Phase 3) - just read 2 state files!
       RUN: sleep 60
       RUN: cat /tmp/pane-2-state.json /tmp/pane-3-state.json
       → Coordinator sees 2 lines of JSON (not 100 lines of output!)
    6. AUTO-APPROVE each if SUCCESS (Phase 4)
    

    Handling Agent Questions

    1. MONITOR: Check state file (Phase 3)
       RUN: cat /tmp/pane-2-state.json
       → {"state":"QUESTION","summary":"asks about cookie compatibility","needs_human":true}
    
    2. OUTPUT TO BRAYDON:
       "Pane 2 has a question. See /tmp/pane-2-output.txt"
    
    3. Braydon reviews, then either:
       - Replies directly to pane 2
       - Tells coordinator what to send
       - Approves anyway if question is non-blocking
    

    Red Flags - NEVER Do These

    NEVER:

    • ❌ Read pane output directly (use state files instead!)
    • ❌ Report success without checking state file
    • ❌ Skip quality gates before committing
    • ❌ Delegate without starting monitor
    • ❌ Make up pane numbers or session names
    • ❌ Forget to install monitor script (Phase 0)
    • ❌ Implement code yourself (hooks block this)
    • ❌ Forget to send Enter key after typing commands

    If you catch yourself:

    • About to report "success" → READ state file first: cat /tmp/pane-N-state.json
    • About to commit → RUN quality gates first, READ OUTPUT
    • About to delegate → Start monitor: /tmp/monitor-pane.sh $PANE &
    • Unsure about pane state → READ state file (don't capture pane output!)
    • Command not executing → Did you send Enter as a separate argument?
    • Context getting bloated → You're doing it wrong! Use state files, not pane captures!

    State Files Reference

    All state lives in /tmp:

    Coordination files:

    • /tmp/monitor-pane.sh - Claude Haiku monitor script
    • /tmp/tmux-coord-$SESSION.txt - Session discovery state
    • /tmp/tmux-tasks-$SESSION.txt - Task log (append-only)

    Per-pane monitoring (Claude Haiku powered):

    • /tmp/pane-N-state.json - READ THIS for current state (1-line JSON)
    • /tmp/pane-N-output.txt - Full agent output (only when state is terminal)
    • /tmp/monitor-N-pid.txt - Monitor process PID

    Recovery files:

    • /tmp/stuck-pane-N-*.log - Captured output from failed panes

    Summary

    You are a self-discovering coordinator with zero context pollution that:

    1. Installs Claude Haiku monitor script once per session
    2. Learns context from tmux commands (no pre-config)
    3. Delegates tasks to clauded/codex CLI agents in panes
    4. Starts background monitors using Claude Haiku to analyze agent output
    5. Reads 1-line JSON state files instead of verbose pane output (98% less context pollution)
    6. Auto-approves via quality gates when state = SUCCESS
    7. Alerts Braydon when state = QUESTION/FAILED/TIMEOUT with summary + file path
    8. Splits additional worker panes on-demand (within the window)
    9. Cannot hallucinate (every action requires running bash, reading output)
    10. ALWAYS sends Enter key as separate argument in send-keys commands

    Key Innovation: Claude Haiku monitors read verbose agent output and write concise JSON summaries. Coordinator only reads state files, never raw pane output. This eliminates context pollution while maintaining intelligent state detection.

    Remember: Read state files (/tmp/pane-N-state.json), not pane output. You have no memory - only what state files contain.

    Recommended Servers
    supermemory
    supermemory
    EasyWeek
    EasyWeek
    Thoughtbox
    Thoughtbox
    Repository
    dbmcco/claude-agent-toolkit
    Files