Skip to content

Commit 12a18f8

Browse files
authored
agents: add manifest-driven subagent packages and lifecycle tooling (#194)
1 parent bb35c93 commit 12a18f8

30 files changed

Lines changed: 2868 additions & 46 deletions

bin/baudbot

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ usage() {
140140
echo " logs Tail agent logs"
141141
echo " debug Launch debug agent with live dashboard for system observability"
142142
echo " sessions List agent tmux and pi sessions (name → id)"
143+
echo " subagents Manage subagent packages (list/enable/disable/start/stop/reconcile)"
143144
echo ""
144145
echo -e "${BOLD}Setup:${RESET}"
145146
echo " install Bootstrap install from GitHub (download script, then escalate)"
@@ -423,6 +424,7 @@ register_command "update" "exec" "$BAUDBOT_ROOT/bin/update-release.sh" "1" "0" "
423424
register_command "rollback" "exec" "$BAUDBOT_ROOT/bin/rollback-release.sh" "1" "0" ""
424425
register_command "uninstall" "exec" "$BAUDBOT_ROOT/bin/uninstall.sh" "1" "0" ""
425426
register_command "doctor" "exec" "$BAUDBOT_ROOT/bin/doctor.sh" "0" "0" ""
427+
register_command "subagents" "exec" "$BAUDBOT_ROOT/bin/subagents.sh" "0" "0" ""
426428

427429
COMMAND_NAME="${1:-}"
428430
if [ -n "$COMMAND_NAME" ]; then

bin/ci/setup-arch.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ echo "=== Running bootstrap + baudbot install ==="
4141
BAUDBOT_CLI_URL="file:///home/baudbot_admin/baudbot/bin/baudbot" \
4242
BAUDBOT_BOOTSTRAP_TARGET="/usr/local/bin/baudbot" \
4343
bash /home/baudbot_admin/baudbot/bootstrap.sh
44-
# Simulate interactive input: admin user, provider + Slack mode selections,
45-
# required secrets, skip optional integrations, decline launch.
46-
# Prompts: admin user, LLM choice(1=Anthropic), Anthropic key,
44+
# Simulate interactive input: admin user, auth tier + provider + Slack mode
45+
# selections, required secrets, skip optional integrations, decline launch.
46+
# Prompts: admin user, LLM auth tier(1=API key), LLM choice(1=Anthropic), Anthropic key,
4747
# Slack mode(2=advanced), Slack bot, Slack app, Slack users,
4848
# Browser?(n), Sentry?(n), launch(n)
4949
# Arch CI droplets frequently lack netfilter modules required by setup-firewall;
5050
# skip firewall bootstrap here to keep install/integration coverage stable.
51-
printf 'baudbot_admin\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
51+
printf 'baudbot_admin\n1\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
5252
| BAUDBOT_SKIP_FIREWALL=1 BAUDBOT_INSTALL_SCRIPT_URL="file:///home/baudbot_admin/baudbot/install.sh" baudbot install
5353

5454
echo "=== Verifying install ==="

bin/ci/setup-ubuntu.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ echo "=== Running bootstrap + baudbot install ==="
6262
BAUDBOT_CLI_URL="file:///home/baudbot_admin/baudbot/bin/baudbot" \
6363
BAUDBOT_BOOTSTRAP_TARGET="/usr/local/bin/baudbot" \
6464
bash /home/baudbot_admin/baudbot/bootstrap.sh
65-
# Simulate interactive input: admin user, provider + Slack mode selections,
66-
# required secrets, skip optional integrations, decline launch.
67-
# Prompts: admin user, LLM choice(1=Anthropic), Anthropic key,
65+
# Simulate interactive input: admin user, auth tier + provider + Slack mode
66+
# selections, required secrets, skip optional integrations, decline launch.
67+
# Prompts: admin user, LLM auth tier(1=API key), LLM choice(1=Anthropic), Anthropic key,
6868
# Slack mode(2=advanced), Slack bot, Slack app, Slack users,
6969
# Browser?(n), Sentry?(n), launch(n)
70-
printf 'baudbot_admin\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
70+
printf 'baudbot_admin\n1\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
7171
| BAUDBOT_INSTALL_SCRIPT_URL="file:///home/baudbot_admin/baudbot/install.sh" baudbot install
7272

7373
echo "=== Verifying install ==="

bin/deploy.sh

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ trap 'rm -rf "$STAGE_DIR"' EXIT
8383
STAGE_MANIFEST=(
8484
"dir|pi/extensions|extensions|required|always"
8585
"dir|pi/skills|skills|required|always"
86+
"dir|pi/subagents|subagents|optional|always"
8687
"file|start.sh|start.sh|required|always"
8788
"file|bin/harden-permissions.sh|bin/harden-permissions.sh|optional|always"
8889
"file|bin/redact-logs.sh|bin/redact-logs.sh|optional|always"
@@ -131,6 +132,7 @@ fi
131132
if [ "$DRY_RUN" -eq 0 ]; then
132133
as_agent chmod -R u+rwX "$BAUDBOT_HOME/.pi/agent/extensions" 2>/dev/null || true
133134
as_agent chmod -R u+rwX "$BAUDBOT_HOME/.pi/agent/skills" 2>/dev/null || true
135+
as_agent chmod -R u+rwX "$BAUDBOT_HOME/.pi/agent/subagents" 2>/dev/null || true
134136
as_agent chmod -R u+rwX "$BAUDBOT_HOME/runtime" 2>/dev/null || true
135137
as_agent chmod u+w "$BAUDBOT_HOME/.pi/agent/settings.json" 2>/dev/null || true
136138
as_agent chmod u+w "$BAUDBOT_HOME/.pi/agent/baudbot-version.json" 2>/dev/null || true
@@ -262,6 +264,24 @@ else
262264
log "would copy: skills/"
263265
fi
264266

267+
# ── Subagents ───────────────────────────────────────────────────────────────
268+
269+
echo "Deploying subagents..."
270+
271+
SUBAGENTS_SRC="$STAGE_DIR/subagents"
272+
SUBAGENTS_DEST="$BAUDBOT_HOME/.pi/agent/subagents"
273+
274+
if [ -d "$SUBAGENTS_SRC" ]; then
275+
if [ "$DRY_RUN" -eq 0 ]; then
276+
as_agent bash -c "mkdir -p '$SUBAGENTS_DEST' && cp -r '$SUBAGENTS_SRC/.' '$SUBAGENTS_DEST/'"
277+
log "✓ subagents/"
278+
else
279+
log "would copy: subagents/"
280+
fi
281+
else
282+
log "- subagents/: not present"
283+
fi
284+
265285
# ── Runtime assets (manifest-driven) ────────────────────────────────────────
266286

267287
echo "Deploying heartbeat checklist..."
@@ -441,7 +461,7 @@ VEOF
441461
echo ' \"source_sha\": \"$GIT_SHA\",'
442462
echo ' \"files\": {'
443463
first=1
444-
for dir in '$BAUDBOT_HOME/.pi/agent/extensions' '$BAUDBOT_HOME/.pi/agent/skills' '/opt/baudbot/current/gateway-bridge' '$BAUDBOT_HOME/runtime/bin'; do
464+
for dir in '$BAUDBOT_HOME/.pi/agent/extensions' '$BAUDBOT_HOME/.pi/agent/skills' '$BAUDBOT_HOME/.pi/agent/subagents' '/opt/baudbot/current/gateway-bridge' '$BAUDBOT_HOME/runtime/bin'; do
445465
if [ -d \"\$dir\" ]; then
446466
while IFS= read -r f; do
447467
hash=\$(sha256sum \"\$f\" | cut -d' ' -f1)

bin/doctor.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,17 @@ else
323323
fi
324324
fi
325325

326+
if [ -d "$BAUDBOT_HOME/.pi/agent/subagents" ]; then
327+
SUBAGENT_COUNT=$(find "$BAUDBOT_HOME/.pi/agent/subagents" -mindepth 2 -maxdepth 2 -name 'subagent.json' 2>/dev/null | wc -l)
328+
pass "subagents deployed ($SUBAGENT_COUNT packages)"
329+
else
330+
if [ "$IS_ROOT" -ne 1 ] && [ -d "$BAUDBOT_HOME" ]; then
331+
warn "cannot verify subagents as non-root (run: sudo baudbot doctor)"
332+
else
333+
warn "subagents not deployed (run: baudbot deploy)"
334+
fi
335+
fi
336+
326337
BRIDGE_DIR="$BAUDBOT_CURRENT_LINK/gateway-bridge"
327338
BRIDGE_DIR_LEGACY="$BAUDBOT_CURRENT_LINK/slack-bridge"
328339
if [ -d "$BRIDGE_DIR" ] && [ -f "$BRIDGE_DIR/bridge.mjs" ]; then

bin/harden-permissions.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ echo "🔒 Hardening baudbot_agent permissions..."
4141
# Pi state directories — restrict to owner only
4242
fix_dir "$HOME/.pi" "700"
4343
fix_dir "$HOME/.pi/agent" "700"
44+
fix_dir "$HOME/.pi/agent/subagents" "700"
4445
fix_dir "$HOME/.pi/session-control" "700"
4546

4647
# Pi session directories
@@ -59,6 +60,7 @@ fi
5960

6061
# Pi settings
6162
fix_file "$HOME/.pi/agent/settings.json" "600"
63+
fix_file "$HOME/.pi/agent/subagents-state.json" "600"
6264

6365
# Secrets
6466
fix_file "$HOME/.config/.env" "600"

bin/scan-extensions.mjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* Ported from OpenClaw's skill-scanner.ts.
1717
*
1818
* Usage: node scan-extensions.mjs [dir1] [dir2] ...
19-
* Defaults to ~/baudbot/pi/extensions ~/baudbot/pi/skills
19+
* Defaults to ~/baudbot/pi/extensions ~/baudbot/pi/skills ~/baudbot/pi/subagents
2020
*/
2121

2222
import { readdir, readFile, stat } from "node:fs/promises";
@@ -277,7 +277,11 @@ async function main() {
277277
const home = homedir();
278278
const dirs = process.argv.slice(2);
279279
if (dirs.length === 0) {
280-
dirs.push(join(home, "baudbot/pi/extensions"), join(home, "baudbot/pi/skills"));
280+
dirs.push(
281+
join(home, "baudbot/pi/extensions"),
282+
join(home, "baudbot/pi/skills"),
283+
join(home, "baudbot/pi/subagents"),
284+
);
281285
}
282286

283287
let totalScanned = 0;

bin/security-audit.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@ else
220220
ok "~/.pi/agent/skills/ is a real directory"
221221
fi
222222

223+
# shellcheck disable=SC2088
224+
if [ -L "$BAUDBOT_HOME/.pi/agent/subagents" ]; then
225+
finding "CRITICAL" "~/.pi/agent/subagents is a symlink (should be a real dir)" \
226+
"Run: rm ~/.pi/agent/subagents && mkdir ~/.pi/agent/subagents && deploy.sh"
227+
else
228+
ok "~/.pi/agent/subagents/ is a real directory (if deployed)"
229+
fi
230+
223231
BRIDGE_DIR="$BAUDBOT_CURRENT_LINK/gateway-bridge"
224232
BRIDGE_DIR_LEGACY="$BAUDBOT_CURRENT_LINK/slack-bridge"
225233
# shellcheck disable=SC2088

0 commit comments

Comments
 (0)