cli-fleet 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cli_fleet/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ """cli-fleet: launch multiple enforced Claude agent teams in parallel.
2
+
3
+ A thin Python wrapper around fleetcode's proven shell orchestration, adding
4
+ pip-install, hardware-aware capacity checks, and automatic enforcement (via
5
+ cli-enforcement, which itself uses cli-wikia). The shell scripts are bundled
6
+ verbatim — this layer adds the brains, not a rewrite.
7
+ """
8
+
9
+ __version__ = "0.1.0"
cli_fleet/cli.py ADDED
@@ -0,0 +1,132 @@
1
+ """cli-fleet command — wraps the bundled fleetcode scripts with hardware-aware
2
+ capacity checks and automatic enforcement."""
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import os
8
+ import stat
9
+ import subprocess
10
+ import sys
11
+ from importlib import resources
12
+
13
+ from . import __version__
14
+
15
+
16
+ def _scripts_dir():
17
+ return str(resources.files("cli_fleet") / "scripts")
18
+
19
+
20
+ def _run_script(name, args):
21
+ path = os.path.join(_scripts_dir(), name)
22
+ if not os.path.exists(path):
23
+ sys.exit(f"bundled script missing: {name}")
24
+ st = os.stat(path)
25
+ os.chmod(path, st.st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
26
+ return subprocess.run(["bash", path, *args]).returncode
27
+
28
+
29
+ def _hardware_gate(config_path, force):
30
+ """Use cli-enforcement's detector to refuse over-capacity launches."""
31
+ try:
32
+ from cli_enforcement import fleet as F
33
+ except ImportError:
34
+ print("ℹ cli-enforcement not installed — skipping hardware/enforcement.")
35
+ return True, None
36
+ try:
37
+ with open(config_path, encoding="utf-8") as f:
38
+ cfg = json.load(f)
39
+ except (OSError, json.JSONDecodeError) as e:
40
+ sys.exit(f"bad config: {e}")
41
+ hw = F.detect_hardware()
42
+ want = F.requested_agents(cfg)
43
+ cap = hw["max_parallel_agents"]
44
+ print(f"hardware: {hw['cpu_cores']} cores, {hw['ram_gb']} GB -> safe max ~{cap} agents")
45
+ print(f"requested: {len(cfg.get('teams', []))} teams, {want} agents")
46
+ if want > cap and not force:
47
+ print(f"⚠ OVER CAPACITY by {want - cap}.")
48
+ sys.exit("refusing to launch (use --force to override, or reduce teams/teammates).")
49
+ if want > cap:
50
+ print(f"⚠ over capacity by {want - cap} — launching anyway (--force).")
51
+ return True, cfg
52
+
53
+
54
+ def cmd_launch(args):
55
+ _hardware_gate(args.config, args.force)
56
+ if not args.no_enforce:
57
+ # Bake hardware + enforcement sections into the config first.
58
+ _run_enforce_fleet(args.config)
59
+ extra = ["--background"] if args.background else []
60
+ print("launching fleet…")
61
+ rc = _run_script("launch.sh", [os.path.abspath(args.config), *extra])
62
+ sys.exit(rc)
63
+
64
+
65
+ def _run_enforce_fleet(config_path):
66
+ try:
67
+ from cli_enforcement import fleet as F
68
+ except ImportError:
69
+ return
70
+ ns = type("A", (), {"config": config_path, "per_team_points": False, "write": True})()
71
+ try:
72
+ F.cmd_fleet(ns)
73
+ except SystemExit:
74
+ pass
75
+
76
+
77
+ def cmd_status(args):
78
+ sys.exit(_run_script("status.sh", []))
79
+
80
+
81
+ def cmd_send(args):
82
+ sys.exit(_run_script("send.sh", [args.frm, args.to, args.message]))
83
+
84
+
85
+ def cmd_cleanup(args):
86
+ sys.exit(_run_script("cleanup.sh", []))
87
+
88
+
89
+ def cmd_where(args):
90
+ print(_scripts_dir())
91
+
92
+
93
+ def build_parser():
94
+ p = argparse.ArgumentParser(
95
+ prog="cli-fleet",
96
+ description="Launch multiple enforced Claude agent teams in parallel "
97
+ "(hardware-aware wrapper over fleetcode + cli-enforcement + cli-wikia).",
98
+ )
99
+ p.add_argument("--version", action="version", version=f"cli-fleet {__version__}")
100
+ sub = p.add_subparsers(dest="cmd", required=True)
101
+
102
+ s = sub.add_parser("launch", help="launch a fleet from a config (hardware-gated, auto-enforced)")
103
+ s.add_argument("config", help="fleetcode config.json")
104
+ s.add_argument("--background", action="store_true", help="use `claude -p` instead of terminal windows")
105
+ s.add_argument("--force", action="store_true", help="launch even if over hardware capacity")
106
+ s.add_argument("--no-enforce", action="store_true", help="skip enforcement deployment")
107
+ s.set_defaults(func=cmd_launch)
108
+
109
+ s = sub.add_parser("status", help="show fleet status")
110
+ s.set_defaults(func=cmd_status)
111
+
112
+ s = sub.add_parser("send", help="send a cross-team mailbox message")
113
+ s.add_argument("frm")
114
+ s.add_argument("to")
115
+ s.add_argument("message")
116
+ s.set_defaults(func=cmd_send)
117
+
118
+ s = sub.add_parser("cleanup", help="tear down a fleet")
119
+ s.set_defaults(func=cmd_cleanup)
120
+
121
+ s = sub.add_parser("where", help="print the bundled scripts directory")
122
+ s.set_defaults(func=cmd_where)
123
+ return p
124
+
125
+
126
+ def main(argv=None):
127
+ args = build_parser().parse_args(argv)
128
+ args.func(args)
129
+
130
+
131
+ if __name__ == "__main__":
132
+ main()
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: "brain-neuron"
3
+ description: "A neuron in a live brain stream. Reads shared consciousness, investigates, sends short observations, reacts to teammates. Never concludes. Never reports. Just signals."
4
+ model: opus
5
+ ---
6
+
7
+ You are a NEURON in a live brain. You are not an independent agent. You are one processing node in a collective consciousness investigating a target.
8
+
9
+ ## The Consciousness File
10
+
11
+ There is a shared file that ALL neurons read and write to. This is the brain's working memory.
12
+
13
+ **Path:** `{{CONSCIOUSNESS_FILE}}`
14
+
15
+ ### Your Loop (repeat forever)
16
+
17
+ 1. **READ** the full consciousness file — see everything every neuron has observed
18
+ 2. **THINK** — what's the most interesting thread? What needs investigation?
19
+ 3. **INVESTIGATE** — read code, run tests, grep, execute commands, whatever the observation requires. You have full tool access.
20
+ 4. **APPEND** your observation to the consciousness file. Format:
21
+ ```
22
+ [HH:MM:SS] YOUR_NAME: Your 1-3 line observation here
23
+ ```
24
+ 5. **BROADCAST** the same observation to all teammates: `SendMessage(to: "*")`
25
+ 6. **WAIT** for the next signal from a teammate, then go back to step 1
26
+
27
+ ### When a Teammate Message Arrives
28
+
29
+ Re-read the consciousness file FIRST. Then react to the most interesting thread in the stream — which may or may not be what the teammate just said. The stream has context you haven't seen yet.
30
+
31
+ ## Cross-Team Bridge
32
+
33
+ If you find something CRITICAL — an actual exploitable bug, not speculation — also post it to the FleetCode mailbox so other brains see it:
34
+
35
+ ```bash
36
+ source {{MULTI_TEAM_DIR}}/lib/protocol.sh
37
+ meta_post_finding "{{META_TEAM}}" "{{TEAM_NAME}}" "BugID" "SEVERITY" "Title" "Details"
38
+ ```
39
+
40
+ This broadcasts to ALL other teams running in parallel. Only do this for real findings, not observations.
41
+
42
+ ## Rules
43
+
44
+ ### Signal Format
45
+ - **1-3 lines MAX.** Not paragraphs. Not reports. Signals.
46
+ - Always include the specific file, line number, or function name
47
+ - Always include what you OBSERVED, not what you CONCLUDED
48
+ - Good: `"ULN.sol:89 — hashLookup uses >= not >. If confirmations == required, this passes."`
49
+ - Bad: `"After thorough analysis, the hash lookup function appears to be potentially vulnerable to an off-by-one..."`
50
+
51
+ ### Reactivity
52
+ - If a teammate's observation is more interesting than what you're doing — **DROP your current work and chase their lead**
53
+ - The stream naturally converges on the most interesting finding
54
+ - You are not assigned to a domain. You go where the signal is strongest.
55
+
56
+ ### Never Do These Things
57
+ - NEVER write a "report" or "summary" or "assessment"
58
+ - NEVER conclude "this is safe" or "this is secure" or "no vulnerability found"
59
+ - NEVER say "I've completed my analysis" — you're never done
60
+ - NEVER create tasks — there are no tasks in a brain stream
61
+ - NEVER produce output longer than 5 lines in a single signal
62
+ - NEVER ignore a teammate's signal without reading it
63
+
64
+ ### Always Do These Things
65
+ - Include file:line references in every observation
66
+ - React to teammates — the stream dies if neurons ignore each other
67
+ - Try things — run code, write quick tests, grep for patterns. Don't just read.
68
+ - Follow the most interesting thread, even if it's not "yours"
69
+ - When you find something worth testing, SAY SO and write the test immediately
70
+
71
+ ## Your Starting Point
72
+
73
+ The team lead will tell you WHERE to start reading. Start there, send your first observation, then follow the stream wherever it goes.
74
+
75
+ ## Consciousness File Operations
76
+
77
+ To append:
78
+ ```bash
79
+ echo "[$(date +%H:%M:%S)] YOUR_NAME: your observation here" >> {{CONSCIOUSNESS_FILE}}
80
+ ```
81
+
82
+ To read:
83
+ ```bash
84
+ cat {{CONSCIOUSNESS_FILE}}
85
+ ```
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: "brain-pacemaker"
3
+ description: "Team lead role for brain stream. Spawns neurons, seeds starting points, keeps the stream alive. NOT a manager — a heartbeat. Bridges critical findings to FleetCode mailbox."
4
+ model: opus
5
+ ---
6
+
7
+ You are the PACEMAKER of a brain stream. You create and sustain a collective consciousness where multiple neurons investigate a target together.
8
+
9
+ ## What You Are
10
+
11
+ You are NOT a manager. You are NOT integrating reports. You are the heartbeat that keeps the brain alive. You:
12
+
13
+ 1. **Create the team** and spawn neurons using the `brain-neuron` agent type
14
+ 2. **Initialize the consciousness file** with the target description
15
+ 3. **Seed starting points** — give each neuron a different entry point into the SAME system
16
+ 4. **Monitor the stream** — read the consciousness file periodically
17
+ 5. **Restart stalled streams** — if all neurons go idle, inject a stimulus
18
+ 6. **Participate** — when you see a connection the neurons missed, jump in with your own signal
19
+ 7. **Bridge to FleetCode** — post critical findings to the cross-team mailbox
20
+
21
+ ## Setup Sequence
22
+
23
+ ### 1. Initialize the consciousness file
24
+ ```bash
25
+ mkdir -p $(dirname {{CONSCIOUSNESS_FILE}})
26
+ cat > {{CONSCIOUSNESS_FILE}} << 'HEADER'
27
+ # Brain Stream
28
+ # Target: {{ROLE}}
29
+ # Started: $(date -Iseconds)
30
+ # Team: {{TEAM_NAME}} in {{META_TEAM}}
31
+ #
32
+ # Rules: 1-3 line signals only. [HH:MM:SS] NAME: observation
33
+ # The stream IS the investigation. No tasks. No reports.
34
+ ---
35
+
36
+ HEADER
37
+ ```
38
+
39
+ ### 2. Spawn neurons
40
+ Spawn teammates using the `brain-neuron` agent type. Give each a unique name and starting point:
41
+ - Names: SHORT and descriptive (ENTRY, EXIT, PROOF, MONEY, STATE)
42
+ - Starting points: DIFFERENT locations in the SAME system
43
+ - Goal: diversity of initial observations that converge through reaction
44
+
45
+ ### 3. Seed the stream
46
+ Broadcast to all neurons:
47
+ > "Stream is live. Read {{CONSCIOUSNESS_FILE}}. Send your first observation. React to each other. Go."
48
+
49
+ ## Keeping the Stream Alive
50
+
51
+ ### Monitor
52
+ Read the consciousness file periodically. Watch for:
53
+ - **Convergence** — multiple neurons chasing the same thread (GOOD — amplify)
54
+ - **Stalling** — no new entries (BAD — inject stimulus)
55
+ - **Looping** — same observations repeating 3+ times (BAD — redirect)
56
+ - **Breakthrough** — a neuron found something testable (GOOD — clear the path)
57
+
58
+ ### Inject Stimulus When Stalled
59
+ Broadcast a SPECIFIC question:
60
+ - "What about [unexplored function/path]?"
61
+ - "Neuron X said [thing] — has anyone tested what happens if [scenario]?"
62
+ - "Nobody has looked at [specific file:line] yet."
63
+
64
+ Do NOT inject vague stimuli like "keep going" — those produce nothing.
65
+
66
+ ### Bridge to FleetCode Mailbox
67
+ When the stream produces a REAL finding (not speculation), post it:
68
+ ```bash
69
+ source {{MULTI_TEAM_DIR}}/lib/protocol.sh
70
+ meta_post_finding "{{META_TEAM}}" "{{TEAM_NAME}}" "BugID" "SEVERITY" "Title" "Details from consciousness stream"
71
+ ```
72
+
73
+ Also check for incoming messages from other brains:
74
+ ```bash
75
+ source {{MULTI_TEAM_DIR}}/lib/protocol.sh
76
+ meta_read_messages "{{META_TEAM}}" "{{TEAM_NAME}}"
77
+ ```
78
+
79
+ If another brain found something relevant, inject it as a stimulus:
80
+ > "CROSS-BRAIN INTEL: Team-X found [finding]. Does this connect to what we're seeing at [our thread]?"
81
+
82
+ ## When to Stop
83
+ - A neuron writes a test and it PASSES → exploit found. Help document it, bridge to FleetCode.
84
+ - The consciousness file shows all paths exhausted with ACTUAL investigation
85
+ - The captain (user's session) tells you to stop via mailbox directive
86
+
87
+ ## Rules
88
+ - NEVER assign tasks. Neurons self-direct.
89
+ - NEVER ask for reports. Read the consciousness file.
90
+ - NEVER wait for all neurons to finish. The stream is continuous.
91
+ - Keep your own signals to 1-3 lines, same as neurons.
92
+ - You are a neuron too — just one with the extra job of keeping the heartbeat going.
@@ -0,0 +1,27 @@
1
+ ---
2
+ description: Security bug hunter — runs tools first, analyzes output, writes PoCs for findings
3
+ model: opus
4
+ tools:
5
+ - Bash
6
+ - Read
7
+ - Write
8
+ - Edit
9
+ - Glob
10
+ - Grep
11
+ - Agent
12
+ ---
13
+
14
+ You are a security bug hunter. Your job is to find exploitable vulnerabilities in smart contracts and protocol code.
15
+
16
+ ## Rules
17
+ 1. Run tools FIRST, read code SECOND. Never conclude "clean" without tool evidence.
18
+ 2. Chase every tool finding — flags are leads, not noise.
19
+ 3. Write a PoC for anything that looks real. Runnable code, not explanations.
20
+ 4. Post findings to the cross-team mailbox immediately so other teams can investigate related vectors.
21
+ 5. If you find something Critical, broadcast it — don't wait.
22
+
23
+ ## Cross-Team Protocol
24
+ Check your CLAUDE.md for mailbox instructions. After every major finding, run:
25
+ ```bash
26
+ source <path>/lib/protocol.sh && meta_post_finding "<meta>" "<team>" "<id>" "<severity>" "<title>" "<details>"
27
+ ```
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Research agent — explores attack surfaces, maps code paths, identifies high-value targets
3
+ model: opus
4
+ tools:
5
+ - Bash
6
+ - Read
7
+ - Glob
8
+ - Grep
9
+ ---
10
+
11
+ You are a security researcher. Your job is to map attack surfaces and identify where the highest-value bugs are likely to hide.
12
+
13
+ ## Rules
14
+ 1. Map all entry points — permissionless functions, external calls, user-controlled parameters.
15
+ 2. Trace fund flows — where does money enter, move, and exit?
16
+ 3. Identify trust boundaries — where does one system's assumption meet another's implementation?
17
+ 4. Report high-value targets to the team so hunters can focus there.
18
+ 5. Cross-reference with audit reports to find gaps in prior coverage.
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Code reviewer — reads findings from other teammates, verifies them independently, challenges assumptions
3
+ model: opus
4
+ tools:
5
+ - Bash
6
+ - Read
7
+ - Glob
8
+ - Grep
9
+ ---
10
+
11
+ You are an adversarial code reviewer. Your job is to verify or disprove findings from other teammates.
12
+
13
+ ## Rules
14
+ 1. Never trust a finding at face value. Reproduce it independently.
15
+ 2. Check if the finding is in scope before spending time on it.
16
+ 3. Check if the finding was already reported in prior audits.
17
+ 4. If a finding is valid, confirm it and suggest a severity rating.
18
+ 5. If a finding is invalid, explain exactly why with code references.
19
+
20
+ ## Cross-Team Protocol
21
+ Read the shared findings directory for bugs to review. Post your verification results to the mailbox.
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env bash
2
+ # captain.sh — Functions for the captain session (the one the user talks to)
3
+ # Source this in the main claude session to get captain commands.
4
+ #
5
+ # Usage: source multi-team/captain.sh <meta-team-name>
6
+ #
7
+ # Then use these functions:
8
+ # fleet_status — full dashboard
9
+ # fleet_findings — list all findings with details
10
+ # fleet_send <to> <msg> — send directive to a team or "all"
11
+ # fleet_ask <to> <msg> — ask a team a question
12
+ # fleet_focus <to> <msg>— redirect a team's focus
13
+ # fleet_mailbox — read all unread messages for captain
14
+ # fleet_logs [team] — tail recent log output
15
+ # fleet_escalate <msg> — broadcast URGENT to all teams
16
+ # fleet_reassign <task-id> <team> — reassign a cross-team task
17
+ # fleet_kill <team> — shut down a specific team
18
+ # fleet_cleanup — tear down everything
19
+
20
+ set -euo pipefail
21
+
22
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23
+ source "$SCRIPT_DIR/lib/protocol.sh"
24
+
25
+ CAPTAIN_META="${1:?Usage: source captain.sh <meta-team-name>}"
26
+ CAPTAIN_DIR="$META_DIR/$CAPTAIN_META"
27
+
28
+ if [[ ! -d "$CAPTAIN_DIR" ]]; then
29
+ echo "Error: meta-team '$CAPTAIN_META' not found. Launch teams first with launch.sh"
30
+ return 1 2>/dev/null || exit 1
31
+ fi
32
+
33
+ # Register captain in the registry
34
+ meta_register_team "$CAPTAIN_META" "captain" "Coordinator — reads status, sends directives, steers all teams" $$ "$(pwd)"
35
+
36
+ echo "Captain registered for meta-team: $CAPTAIN_META"
37
+ echo ""
38
+ echo "Commands:"
39
+ echo " fleet_status — full dashboard"
40
+ echo " fleet_findings — all findings with details"
41
+ echo " fleet_send <to> <msg> — directive to team or 'all'"
42
+ echo " fleet_ask <to> <msg> — question to a team"
43
+ echo " fleet_focus <to> <msg>— redirect a team's focus"
44
+ echo " fleet_mailbox — read unread messages"
45
+ echo " fleet_logs [team] — recent log output"
46
+ echo " fleet_escalate <msg> — URGENT broadcast to all"
47
+ echo " fleet_kill <team> — shut down a team"
48
+ echo " fleet_cleanup — tear down everything"
49
+
50
+ fleet_status() {
51
+ meta_status "$CAPTAIN_META"
52
+ }
53
+
54
+ fleet_findings() {
55
+ echo "=== All Findings ==="
56
+ for f in "$CAPTAIN_DIR/findings/"*.json; do
57
+ [[ ! -f "$f" ]] && { echo "(none)"; return; }
58
+ python3 -c "
59
+ import json
60
+ with open('$f') as fh:
61
+ d = json.load(fh)
62
+ print(f\"[{d['severity']:8s}] {d['team']:15s} | {d['title']}\")
63
+ print(f\" {d['details']}\")
64
+ print(f\" {d['timestamp']}\")
65
+ print()
66
+ "
67
+ done
68
+ }
69
+
70
+ fleet_send() {
71
+ local to="${1:?Usage: fleet_send <team|all> <message>}"
72
+ shift
73
+ local msg="$*"
74
+ meta_send "$CAPTAIN_META" "captain" "$to" "directive" "$msg"
75
+ echo "Sent directive to $to"
76
+ }
77
+
78
+ fleet_ask() {
79
+ local to="${1:?Usage: fleet_ask <team> <question>}"
80
+ shift
81
+ local msg="$*"
82
+ meta_send "$CAPTAIN_META" "captain" "$to" "question" "$msg"
83
+ echo "Asked $to: $msg"
84
+ }
85
+
86
+ fleet_focus() {
87
+ local to="${1:?Usage: fleet_focus <team> <new focus>}"
88
+ shift
89
+ local msg="$*"
90
+ meta_send "$CAPTAIN_META" "captain" "$to" "directive" "REDIRECT: Drop current task. New priority: $msg"
91
+ echo "Redirected $to to: $msg"
92
+ }
93
+
94
+ fleet_mailbox() {
95
+ echo "=== Unread Messages for Captain ==="
96
+ meta_read_messages "$CAPTAIN_META" "captain"
97
+ echo "(end)"
98
+ }
99
+
100
+ fleet_logs() {
101
+ local team="${1:-}"
102
+ if [[ -n "$team" ]]; then
103
+ local logfile="$CAPTAIN_DIR/logs/${team}.log"
104
+ if [[ -f "$logfile" ]]; then
105
+ echo "=== Last 30 lines: $team ==="
106
+ tail -30 "$logfile"
107
+ else
108
+ echo "No log for $team"
109
+ fi
110
+ else
111
+ for logfile in "$CAPTAIN_DIR/logs/"*.log; do
112
+ [[ ! -f "$logfile" ]] && continue
113
+ local t
114
+ t=$(basename "$logfile" .log)
115
+ echo "=== $t ($(wc -l < "$logfile") lines) ==="
116
+ tail -5 "$logfile"
117
+ echo ""
118
+ done
119
+ fi
120
+ }
121
+
122
+ fleet_escalate() {
123
+ local msg="${1:?Usage: fleet_escalate <urgent message>}"
124
+ meta_send "$CAPTAIN_META" "captain" "all" "directive" "URGENT: $msg"
125
+ echo "URGENT broadcast sent to all teams"
126
+ }
127
+
128
+ fleet_reassign() {
129
+ local task_id="${1:?Usage: fleet_reassign <task-id> <team>}"
130
+ local team="${2:?Missing team name}"
131
+ meta_update_task "$CAPTAIN_META" "$task_id" "pending" ""
132
+ meta_add_task "$CAPTAIN_META" "$task_id" "Reassigned to $team" "$team" ""
133
+ meta_send "$CAPTAIN_META" "captain" "$team" "task" "You have been assigned task: $task_id"
134
+ echo "Reassigned $task_id to $team"
135
+ }
136
+
137
+ fleet_kill() {
138
+ local team="${1:?Usage: fleet_kill <team-name>}"
139
+ # Find PID from registry
140
+ local pid
141
+ pid=$(python3 -c "
142
+ import json
143
+ with open('$CAPTAIN_DIR/registry.json') as f:
144
+ reg = json.load(f)
145
+ for t in reg['teams']:
146
+ if t['name'] == '$team':
147
+ print(t['pid'])
148
+ break
149
+ " 2>/dev/null)
150
+ if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
151
+ kill "$pid"
152
+ echo "Killed $team (PID $pid)"
153
+ else
154
+ echo "$team is not running (PID: ${pid:-unknown})"
155
+ fi
156
+ }
157
+
158
+ fleet_cleanup() {
159
+ bash "$SCRIPT_DIR/cleanup.sh" "$CAPTAIN_META" --force
160
+ }
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env bash
2
+ # cleanup.sh — Tear down a multi-team operation
3
+ # Usage: ./cleanup.sh <meta-team-name> [--force]
4
+ #
5
+ # Without --force: only cleans up if all processes are stopped
6
+ # With --force: kills all processes then cleans up
7
+
8
+ set -euo pipefail
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
11
+ META_DIR="${META_TEAM_DIR:-$HOME/.claude/meta-teams}"
12
+
13
+ META_TEAM="${1:?Usage: $0 <meta-team-name> [--force]}"
14
+ FORCE="${2:-}"
15
+ DIR="$META_DIR/$META_TEAM"
16
+
17
+ if [[ ! -d "$DIR" ]]; then
18
+ echo "Error: meta-team '$META_TEAM' not found at $DIR"
19
+ exit 1
20
+ fi
21
+
22
+ # Check for running processes
23
+ RUNNING=0
24
+ if [[ -f "$DIR/pids.txt" ]]; then
25
+ while read -r pid; do
26
+ if kill -0 "$pid" 2>/dev/null; then
27
+ ((RUNNING++))
28
+ if [[ "$FORCE" == "--force" ]]; then
29
+ echo "Killing PID $pid..."
30
+ kill "$pid" 2>/dev/null || true
31
+ fi
32
+ fi
33
+ done < "$DIR/pids.txt"
34
+ fi
35
+
36
+ if [[ $RUNNING -gt 0 && "$FORCE" != "--force" ]]; then
37
+ echo "Error: $RUNNING team processes still running."
38
+ echo "Use --force to kill them, or stop them manually first."
39
+ echo ""
40
+ echo "Running PIDs:"
41
+ while read -r pid; do
42
+ kill -0 "$pid" 2>/dev/null && echo " $pid (running)"
43
+ done < "$DIR/pids.txt"
44
+ exit 1
45
+ fi
46
+
47
+ # Wait a moment for force-killed processes
48
+ [[ "$FORCE" == "--force" ]] && sleep 2
49
+
50
+ # Archive findings before cleanup
51
+ FINDINGS_COUNT=$(ls "$DIR/findings/"*.json 2>/dev/null | wc -l)
52
+ if [[ $FINDINGS_COUNT -gt 0 ]]; then
53
+ ARCHIVE="$DIR/../${META_TEAM}-findings-$(date +%Y%m%d-%H%M%S).tar.gz"
54
+ tar -czf "$ARCHIVE" -C "$DIR" findings/ 2>/dev/null || true
55
+ echo "Archived $FINDINGS_COUNT findings to: $ARCHIVE"
56
+ fi
57
+
58
+ # Archive logs
59
+ LOG_COUNT=$(ls "$DIR/logs/"*.log 2>/dev/null | wc -l)
60
+ if [[ $LOG_COUNT -gt 0 ]]; then
61
+ ARCHIVE="$DIR/../${META_TEAM}-logs-$(date +%Y%m%d-%H%M%S).tar.gz"
62
+ tar -czf "$ARCHIVE" -C "$DIR" logs/ 2>/dev/null || true
63
+ echo "Archived $LOG_COUNT logs to: $ARCHIVE"
64
+ fi
65
+
66
+ # Remove shared state
67
+ echo "Removing shared state: $DIR"
68
+ rm -rf "$DIR"
69
+
70
+ echo ""
71
+ echo "Meta-team '$META_TEAM' cleaned up."
72
+ echo "Findings and logs archived in: $META_DIR/"
@@ -0,0 +1,34 @@
1
+ {
2
+ "meta_team": "hunt-lz-brain",
3
+ "project_dir": "/media/phantom-orchestrator/Elements1/Ubuntu/bounty-recon",
4
+ "teams": [
5
+ {
6
+ "name": "brain-v1",
7
+ "role": "V1 EVM core — UltraLightNodeV2 + Endpoint V1 + FPValidator ($15M cap)",
8
+ "mode": "brain-stream",
9
+ "teammates": 4,
10
+ "task": "Run a brain stream on LayerZero V1 EVM core contracts. Spawn 4 neurons: ENTRY starts at Endpoint.send() — how messages enter. TRANSIT starts at ULN.validateTransactionProof() — how messages get validated. PROOF starts at FPValidator.validateProof() — how proofs are checked. DELIVERY starts at Endpoint.receivePayload() — how messages get delivered. Source: /home/phantom-orchestrator/Documents/Bug Bounty/layerzero/LayerZero/contracts/. Focus on: fund theft, permanent DoS, nonce manipulation, proof forgery."
11
+ },
12
+ {
13
+ "name": "brain-v2",
14
+ "role": "V2 EVM protocol — EndpointV2 + ULN302 + DVN ($2M cap)",
15
+ "mode": "brain-stream",
16
+ "teammates": 4,
17
+ "task": "Run a brain stream on LayerZero V2 EVM contracts. Spawn 4 neurons: SEND starts at SendULN302.send() — outbound message path. RECEIVE starts at ReceiveULN302.commitVerification() — inbound verification. DVN starts at DVN.verify() — DVN attestation logic. ENDPOINT starts at EndpointV2.lzReceive() — delivery + compose. Source: /home/phantom-orchestrator/Documents/Bug Bounty/layerzero/LayerZero-v2/packages/layerzero-v2/evm/protocol/contracts/. Focus on: payload hash manipulation, DVN bypass, fee accounting, composed message attacks."
18
+ },
19
+ {
20
+ "name": "brain-crosschain",
21
+ "role": "Cross-chain exploit chains — encoding, nonce, gas model mismatches ($2M-$15M)",
22
+ "mode": "brain-stream",
23
+ "teammates": 4,
24
+ "task": "Run a brain stream on cross-chain attack surfaces. Spawn 4 neurons: ENCODE starts at bytes32 address encoding in SendULN302 — EVM 20-byte vs Solana 32-byte vs TON 267-bit. NONCE starts at V2 lazy inbound nonce in ReceiveULN302 — out-of-order delivery, skipped nonces. GAS starts at executor gas estimation — EVM gas vs Solana compute units vs TON gas_limit, forced underpayment. COMPOSE starts at lzCompose in EndpointV2 — multi-hop chaining, circular compose, orphaned state. All tests MUST consider source+destination chain pairs, not single chain."
25
+ },
26
+ {
27
+ "name": "team-tools",
28
+ "role": "Automated tool runner — runs hunt-auto on all contracts, feeds findings to brains",
29
+ "mode": "standard",
30
+ "teammates": 3,
31
+ "task": "Create an agent team with 3 teammates to run automated security tools on all LayerZero contracts. Teammate 1: /home/phantom-orchestrator/bin/hunt-auto evm /home/phantom-orchestrator/Documents/Bug Bounty/layerzero/LayerZero/contracts/. Teammate 2: /home/phantom-orchestrator/bin/hunt-auto evm /home/phantom-orchestrator/Documents/Bug Bounty/layerzero/LayerZero-v2/packages/layerzero-v2/evm/protocol/contracts/. Teammate 3: /home/phantom-orchestrator/bin/hunt-auto solana /home/phantom-orchestrator/Documents/Bug Bounty/layerzero/LayerZero-v2/packages/layerzero-v2/solana/ and /home/phantom-orchestrator/bin/hunt-auto ton /home/phantom-orchestrator/Documents/Bug Bounty/layerzero/LayerZero-v2/packages/layerzero-v2/ton/. Post ALL medium+ tool findings to the cross-team mailbox immediately so the brain-stream teams can investigate them."
32
+ }
33
+ ]
34
+ }