Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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