Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bin/baudbot
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ usage() {
echo " logs Tail agent logs"
echo " debug Launch debug agent with live dashboard for system observability"
echo " sessions List agent tmux and pi sessions (name → id)"
echo " subagents Manage subagent packages (list/enable/disable/start/stop/reconcile)"
echo ""
echo -e "${BOLD}Setup:${RESET}"
echo " install Bootstrap install from GitHub (download script, then escalate)"
Expand Down Expand Up @@ -422,6 +423,7 @@ register_command "update" "exec" "$BAUDBOT_ROOT/bin/update-release.sh" "1" "0" "
register_command "rollback" "exec" "$BAUDBOT_ROOT/bin/rollback-release.sh" "1" "0" ""
register_command "uninstall" "exec" "$BAUDBOT_ROOT/bin/uninstall.sh" "1" "0" ""
register_command "doctor" "exec" "$BAUDBOT_ROOT/bin/doctor.sh" "0" "0" ""
register_command "subagents" "exec" "$BAUDBOT_ROOT/bin/subagents.sh" "0" "0" ""

COMMAND_NAME="${1:-}"
if [ -n "$COMMAND_NAME" ]; then
Expand Down
8 changes: 4 additions & 4 deletions bin/ci/setup-arch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ echo "=== Running bootstrap + baudbot install ==="
BAUDBOT_CLI_URL="file:///home/baudbot_admin/baudbot/bin/baudbot" \
BAUDBOT_BOOTSTRAP_TARGET="/usr/local/bin/baudbot" \
bash /home/baudbot_admin/baudbot/bootstrap.sh
# Simulate interactive input: admin user, provider + Slack mode selections,
# required secrets, skip optional integrations, decline launch.
# Prompts: admin user, LLM choice(1=Anthropic), Anthropic key,
# Simulate interactive input: admin user, auth tier + provider + Slack mode
# selections, required secrets, skip optional integrations, decline launch.
# Prompts: admin user, LLM auth tier(1=API key), LLM choice(1=Anthropic), Anthropic key,
# Slack mode(2=advanced), Slack bot, Slack app, Slack users,
# Browser?(n), Sentry?(n), launch(n)
# Arch CI droplets frequently lack netfilter modules required by setup-firewall;
# skip firewall bootstrap here to keep install/integration coverage stable.
printf 'baudbot_admin\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
printf 'baudbot_admin\n1\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
| BAUDBOT_SKIP_FIREWALL=1 BAUDBOT_INSTALL_SCRIPT_URL="file:///home/baudbot_admin/baudbot/install.sh" baudbot install

echo "=== Verifying install ==="
Expand Down
8 changes: 4 additions & 4 deletions bin/ci/setup-ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ echo "=== Running bootstrap + baudbot install ==="
BAUDBOT_CLI_URL="file:///home/baudbot_admin/baudbot/bin/baudbot" \
BAUDBOT_BOOTSTRAP_TARGET="/usr/local/bin/baudbot" \
bash /home/baudbot_admin/baudbot/bootstrap.sh
# Simulate interactive input: admin user, provider + Slack mode selections,
# required secrets, skip optional integrations, decline launch.
# Prompts: admin user, LLM choice(1=Anthropic), Anthropic key,
# Simulate interactive input: admin user, auth tier + provider + Slack mode
# selections, required secrets, skip optional integrations, decline launch.
# Prompts: admin user, LLM auth tier(1=API key), LLM choice(1=Anthropic), Anthropic key,
# Slack mode(2=advanced), Slack bot, Slack app, Slack users,
# Browser?(n), Sentry?(n), launch(n)
printf 'baudbot_admin\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
printf 'baudbot_admin\n1\n1\nsk-ant-testkey\n2\nxoxb-test\nxapp-test\nU01TEST\nn\nn\nn\n' \
| BAUDBOT_INSTALL_SCRIPT_URL="file:///home/baudbot_admin/baudbot/install.sh" baudbot install

echo "=== Verifying install ==="
Expand Down
22 changes: 21 additions & 1 deletion bin/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ trap 'rm -rf "$STAGE_DIR"' EXIT
STAGE_MANIFEST=(
"dir|pi/extensions|extensions|required|always"
"dir|pi/skills|skills|required|always"
"dir|pi/subagents|subagents|optional|always"
"file|start.sh|start.sh|required|always"
"file|bin/harden-permissions.sh|bin/harden-permissions.sh|optional|always"
"file|bin/redact-logs.sh|bin/redact-logs.sh|optional|always"
Expand Down Expand Up @@ -131,6 +132,7 @@ fi
if [ "$DRY_RUN" -eq 0 ]; then
as_agent chmod -R u+rwX "$BAUDBOT_HOME/.pi/agent/extensions" 2>/dev/null || true
as_agent chmod -R u+rwX "$BAUDBOT_HOME/.pi/agent/skills" 2>/dev/null || true
as_agent chmod -R u+rwX "$BAUDBOT_HOME/.pi/agent/subagents" 2>/dev/null || true
as_agent chmod -R u+rwX "$BAUDBOT_HOME/runtime" 2>/dev/null || true
as_agent chmod u+w "$BAUDBOT_HOME/.pi/agent/settings.json" 2>/dev/null || true
as_agent chmod u+w "$BAUDBOT_HOME/.pi/agent/baudbot-version.json" 2>/dev/null || true
Expand Down Expand Up @@ -262,6 +264,24 @@ else
log "would copy: skills/"
fi

# ── Subagents ───────────────────────────────────────────────────────────────

echo "Deploying subagents..."

SUBAGENTS_SRC="$STAGE_DIR/subagents"
SUBAGENTS_DEST="$BAUDBOT_HOME/.pi/agent/subagents"

if [ -d "$SUBAGENTS_SRC" ]; then
if [ "$DRY_RUN" -eq 0 ]; then
as_agent bash -c "mkdir -p '$SUBAGENTS_DEST' && cp -r '$SUBAGENTS_SRC/.' '$SUBAGENTS_DEST/'"
log "✓ subagents/"
else
log "would copy: subagents/"
fi
else
log "- subagents/: not present"
fi

# ── Runtime assets (manifest-driven) ────────────────────────────────────────

echo "Deploying heartbeat checklist..."
Expand Down Expand Up @@ -441,7 +461,7 @@ VEOF
echo ' \"source_sha\": \"$GIT_SHA\",'
echo ' \"files\": {'
first=1
for dir in '$BAUDBOT_HOME/.pi/agent/extensions' '$BAUDBOT_HOME/.pi/agent/skills' '/opt/baudbot/current/gateway-bridge' '$BAUDBOT_HOME/runtime/bin'; do
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
if [ -d \"\$dir\" ]; then
while IFS= read -r f; do
hash=\$(sha256sum \"\$f\" | cut -d' ' -f1)
Expand Down
11 changes: 11 additions & 0 deletions bin/doctor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,17 @@ else
fi
fi

if [ -d "$BAUDBOT_HOME/.pi/agent/subagents" ]; then
SUBAGENT_COUNT=$(find "$BAUDBOT_HOME/.pi/agent/subagents" -mindepth 2 -maxdepth 2 -name 'subagent.json' 2>/dev/null | wc -l)
pass "subagents deployed ($SUBAGENT_COUNT packages)"
else
if [ "$IS_ROOT" -ne 1 ] && [ -d "$BAUDBOT_HOME" ]; then
warn "cannot verify subagents as non-root (run: sudo baudbot doctor)"
else
warn "subagents not deployed (run: baudbot deploy)"
fi
fi

BRIDGE_DIR="$BAUDBOT_CURRENT_LINK/gateway-bridge"
BRIDGE_DIR_LEGACY="$BAUDBOT_CURRENT_LINK/slack-bridge"
if [ -d "$BRIDGE_DIR" ] && [ -f "$BRIDGE_DIR/bridge.mjs" ]; then
Expand Down
2 changes: 2 additions & 0 deletions bin/harden-permissions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ echo "🔒 Hardening baudbot_agent permissions..."
# Pi state directories — restrict to owner only
fix_dir "$HOME/.pi" "700"
fix_dir "$HOME/.pi/agent" "700"
fix_dir "$HOME/.pi/agent/subagents" "700"
fix_dir "$HOME/.pi/session-control" "700"

# Pi session directories
Expand All @@ -59,6 +60,7 @@ fi

# Pi settings
fix_file "$HOME/.pi/agent/settings.json" "600"
fix_file "$HOME/.pi/agent/subagents-state.json" "600"

# Secrets
fix_file "$HOME/.config/.env" "600"
Expand Down
8 changes: 6 additions & 2 deletions bin/scan-extensions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* Ported from OpenClaw's skill-scanner.ts.
*
* Usage: node scan-extensions.mjs [dir1] [dir2] ...
* Defaults to ~/baudbot/pi/extensions ~/baudbot/pi/skills
* Defaults to ~/baudbot/pi/extensions ~/baudbot/pi/skills ~/baudbot/pi/subagents
*/

import { readdir, readFile, stat } from "node:fs/promises";
Expand Down Expand Up @@ -277,7 +277,11 @@ async function main() {
const home = homedir();
const dirs = process.argv.slice(2);
if (dirs.length === 0) {
dirs.push(join(home, "baudbot/pi/extensions"), join(home, "baudbot/pi/skills"));
dirs.push(
join(home, "baudbot/pi/extensions"),
join(home, "baudbot/pi/skills"),
join(home, "baudbot/pi/subagents"),
);
}

let totalScanned = 0;
Expand Down
8 changes: 8 additions & 0 deletions bin/security-audit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ else
ok "~/.pi/agent/skills/ is a real directory"
fi

# shellcheck disable=SC2088
if [ -L "$BAUDBOT_HOME/.pi/agent/subagents" ]; then
finding "CRITICAL" "~/.pi/agent/subagents is a symlink (should be a real dir)" \
"Run: rm ~/.pi/agent/subagents && mkdir ~/.pi/agent/subagents && deploy.sh"
else
ok "~/.pi/agent/subagents/ is a real directory (if deployed)"
fi

BRIDGE_DIR="$BAUDBOT_CURRENT_LINK/gateway-bridge"
BRIDGE_DIR_LEGACY="$BAUDBOT_CURRENT_LINK/slack-bridge"
# shellcheck disable=SC2088
Expand Down
Loading