diff --git a/.c8rc.json b/.c8rc.json index 8dbc4ea..d81178c 100644 --- a/.c8rc.json +++ b/.c8rc.json @@ -1,7 +1,7 @@ { "all": false, "include": [ - "slack-bridge/security.mjs", + "gateway-bridge/security.mjs", "bin/scan-extensions.mjs" ], "exclude": [ diff --git a/.gitignore b/.gitignore index cff6e8e..f320650 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ *.pem node_modules/ # Gateway bridge +gateway-bridge/node_modules/ +gateway-bridge/.env +# Legacy compat path (symlink) slack-bridge/node_modules/ slack-bridge/.env .pi/ diff --git a/AGENTS.md b/AGENTS.md index c350daa..e81c6fb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,7 +5,7 @@ Baudbot is hardened infrastructure for running always-on AI agents. Use this file for **repo-wide** guidance. For directory-specific rules, use the nearest nested `AGENTS.md`: - [`bin/AGENTS.md`](bin/AGENTS.md) - [`pi/extensions/AGENTS.md`](pi/extensions/AGENTS.md) -- [`slack-bridge/AGENTS.md`](slack-bridge/AGENTS.md) +- [`gateway-bridge/AGENTS.md`](gateway-bridge/AGENTS.md) ## How Baudbot works @@ -16,7 +16,7 @@ Baudbot is a persistent, team-facing coding agent system. It connects to Slack, ```text Slack ↓ -Gateway bridge (slack-bridge dir; broker pull-mode or legacy Socket Mode) +Gateway bridge (gateway-bridge dir; broker pull-mode or legacy Socket Mode) ↓ control-agent (always-on, manages todo/routing/Slack threads) ├── dev-agent(s) — ephemeral coding workers in isolated worktrees @@ -47,7 +47,8 @@ There are two startup phases with distinct ownership: - `dev-agent/` — coding worker persona - `sentry-agent/` — incident triage persona - `pi/settings.json` — pi agent settings -- `slack-bridge/` — Gateway bridge runtime + security module +- `gateway-bridge/` — Gateway bridge runtime + security module +- `slack-bridge` → symlink to `gateway-bridge/` (legacy compatibility shim) - `docs/` — architecture/operations/security documentation - `test/` — vitest wrappers for shell scripts, integration, and legacy Node tests - `hooks/` — git hooks (security-critical `pre-commit` protecting admin-managed files) diff --git a/bin/ci/setup-arch.sh b/bin/ci/setup-arch.sh index bf3f7dd..3d128c2 100755 --- a/bin/ci/setup-arch.sh +++ b/bin/ci/setup-arch.sh @@ -96,7 +96,7 @@ echo "=== Installing test dependencies ===" export PATH="/home/baudbot_agent/opt/node/bin:$PATH" cd /home/baudbot_admin/baudbot npm install --ignore-scripts 2>&1 | tail -1 -cd slack-bridge && npm install 2>&1 | tail -1 +cd gateway-bridge && npm install 2>&1 | tail -1 cd .. echo "=== Running tests ===" diff --git a/bin/ci/setup-ubuntu.sh b/bin/ci/setup-ubuntu.sh index 10ed0b6..9f01557 100755 --- a/bin/ci/setup-ubuntu.sh +++ b/bin/ci/setup-ubuntu.sh @@ -115,7 +115,7 @@ echo "=== Installing test dependencies ===" export PATH="/home/baudbot_agent/opt/node/bin:$PATH" cd /home/baudbot_admin/baudbot npm install --ignore-scripts 2>&1 | tail -1 -cd slack-bridge && npm install 2>&1 | tail -1 +cd gateway-bridge && npm install 2>&1 | tail -1 cd .. echo "=== Running tests ===" diff --git a/bin/ci/smoke-agent-runtime.sh b/bin/ci/smoke-agent-runtime.sh index 68e37cd..641a4d4 100755 --- a/bin/ci/smoke-agent-runtime.sh +++ b/bin/ci/smoke-agent-runtime.sh @@ -15,7 +15,8 @@ readonly AGENT_USER="baudbot_agent" readonly AGENT_HOME="/home/${AGENT_USER}" readonly CONTROL_DIR="${AGENT_HOME}/.pi/session-control" readonly CONTROL_ALIAS="${CONTROL_DIR}/control-agent.alias" -readonly BRIDGE_STATUS_FILE="${AGENT_HOME}/.pi/agent/slack-bridge-supervisor.json" +readonly BRIDGE_STATUS_FILE="${AGENT_HOME}/.pi/agent/gateway-bridge-supervisor.json" +readonly BRIDGE_STATUS_FILE_LEGACY="${AGENT_HOME}/.pi/agent/slack-bridge-supervisor.json" readonly START_TIMEOUT_SECONDS=60 readonly STABILIZE_SECONDS=20 @@ -143,7 +144,7 @@ main() { # start.sh. In CI the agent doesn't run long enough for startup-pi.sh # to execute, so the status file may not exist. Log but don't fail. log "checking bridge supervisor status file" - if [[ -f "$BRIDGE_STATUS_FILE" ]]; then + if [[ -f "$BRIDGE_STATUS_FILE" ]] || [[ -f "$BRIDGE_STATUS_FILE_LEGACY" ]]; then log "bridge supervisor status file exists" else log "bridge supervisor status file not found (expected — bridge starts inside agent)" diff --git a/bin/deploy.sh b/bin/deploy.sh index 50d00cb..21212e7 100755 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -325,12 +325,12 @@ deploy_runtime_asset_entry() { bb_manifest_for_each RUNTIME_ASSET_MANIFEST deploy_runtime_asset_entry -# Clean up legacy bridge runtime path; bridge now runs from /opt release only. +# Clean up legacy bridge runtime paths; bridge now runs from /opt release only. if [ "$DRY_RUN" -eq 0 ]; then - as_agent bash -c "rm -rf '$BAUDBOT_HOME/runtime/slack-bridge'" - log "✓ removed legacy runtime/slack-bridge" + as_agent bash -c "rm -rf '$BAUDBOT_HOME/runtime/gateway-bridge' '$BAUDBOT_HOME/runtime/slack-bridge'" + log "✓ removed legacy runtime/gateway-bridge and runtime/slack-bridge" else - log "would remove: runtime/slack-bridge (legacy path)" + log "would remove: runtime/gateway-bridge and runtime/slack-bridge (legacy paths)" fi # ── Memory Seeds ───────────────────────────────────────────────────────────── @@ -441,7 +441,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/slack-bridge' '$BAUDBOT_HOME/runtime/bin'; do + for dir in '$BAUDBOT_HOME/.pi/agent/extensions' '$BAUDBOT_HOME/.pi/agent/skills' '/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) diff --git a/bin/doctor.sh b/bin/doctor.sh index d74bdf5..77d6168 100755 --- a/bin/doctor.sh +++ b/bin/doctor.sh @@ -307,14 +307,17 @@ else fi fi -BRIDGE_DIR="$BAUDBOT_CURRENT_LINK/slack-bridge" +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 pass "gateway bridge deployed ($BRIDGE_DIR)" +elif [ -d "$BRIDGE_DIR_LEGACY" ] && [ -f "$BRIDGE_DIR_LEGACY/bridge.mjs" ]; then + pass "gateway bridge deployed via legacy path ($BRIDGE_DIR_LEGACY)" else if [ "$IS_ROOT" -ne 1 ] && { [ -d "$BAUDBOT_CURRENT_LINK" ] || [ -e "$BAUDBOT_CURRENT_LINK" ]; }; then warn "cannot verify gateway bridge files as non-root (run: sudo baudbot doctor)" else - fail "gateway bridge not deployed (expected: $BRIDGE_DIR; run: sudo baudbot update)" + fail "gateway bridge not deployed (expected: $BRIDGE_DIR or $BRIDGE_DIR_LEGACY; run: sudo baudbot update)" fi fi diff --git a/bin/lib/baudbot-runtime.sh b/bin/lib/baudbot-runtime.sh index a63ebab..68ce612 100644 --- a/bin/lib/baudbot-runtime.sh +++ b/bin/lib/baudbot-runtime.sh @@ -195,7 +195,8 @@ PY print_bridge_supervisor_status() { local agent_user="${BAUDBOT_AGENT_USER:-baudbot_agent}" - local status_file="/home/$agent_user/.pi/agent/slack-bridge-supervisor.json" + local status_file="/home/$agent_user/.pi/agent/gateway-bridge-supervisor.json" + local legacy_status_file="/home/$agent_user/.pi/agent/slack-bridge-supervisor.json" local summary="" local mode="" local state="" @@ -203,7 +204,11 @@ print_bridge_supervisor_status() { local threshold="" if [ ! -r "$status_file" ]; then - return 0 + if [ -r "$legacy_status_file" ]; then + status_file="$legacy_status_file" + else + return 0 + fi fi summary="$(python3 - "$status_file" <<'PY' diff --git a/bin/security-audit.sh b/bin/security-audit.sh index 52e1be1..a7a33e8 100755 --- a/bin/security-audit.sh +++ b/bin/security-audit.sh @@ -220,13 +220,17 @@ else ok "~/.pi/agent/skills/ is a real directory" fi -BRIDGE_DIR="$BAUDBOT_CURRENT_LINK/slack-bridge" +BRIDGE_DIR="$BAUDBOT_CURRENT_LINK/gateway-bridge" +BRIDGE_DIR_LEGACY="$BAUDBOT_CURRENT_LINK/slack-bridge" # shellcheck disable=SC2088 if [ -d "$BRIDGE_DIR" ]; then ok "Release bridge directory exists ($BRIDGE_DIR)" +elif [ -d "$BRIDGE_DIR_LEGACY" ]; then + ok "Release bridge directory exists via legacy path ($BRIDGE_DIR_LEGACY)" + BRIDGE_DIR="$BRIDGE_DIR_LEGACY" else finding "WARN" "release bridge directory not found" \ - "Expected: $BRIDGE_DIR (run: sudo baudbot update)" + "Expected: $BRIDGE_DIR or $BRIDGE_DIR_LEGACY (run: sudo baudbot update)" fi # Check version stamp exists @@ -252,21 +256,34 @@ if [ -f "$MANIFEST_FILE" ]; then for critical_file in \ ".pi/agent/extensions/tool-guard.ts" \ ".pi/agent/extensions/tool-guard.test.mjs" \ - "release/slack-bridge/security.mjs" \ - "release/slack-bridge/security.test.mjs"; do + "release/gateway-bridge/security.mjs" \ + "release/gateway-bridge/security.test.mjs"; do if [[ "$critical_file" == release/* ]]; then full_path="$BAUDBOT_CURRENT_LINK/${critical_file#release/}" else full_path="$BAUDBOT_HOME/$critical_file" fi + + expected_hash=$(grep "\"$critical_file\"" "$MANIFEST_FILE" 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "") + + # Legacy compatibility: manifests from older releases used release/slack-bridge/* keys. + if [[ "$critical_file" == "release/gateway-bridge/security.mjs" ]] && [ -z "$expected_hash" ]; then + critical_file="release/slack-bridge/security.mjs" + full_path="$BAUDBOT_CURRENT_LINK/slack-bridge/security.mjs" + expected_hash=$(grep "\"$critical_file\"" "$MANIFEST_FILE" 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "") + elif [[ "$critical_file" == "release/gateway-bridge/security.test.mjs" ]] && [ -z "$expected_hash" ]; then + critical_file="release/slack-bridge/security.test.mjs" + full_path="$BAUDBOT_CURRENT_LINK/slack-bridge/security.test.mjs" + expected_hash=$(grep "\"$critical_file\"" "$MANIFEST_FILE" 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "") + fi + if [ ! -f "$full_path" ]; then finding "WARN" "Missing critical file: $critical_file" "Run deploy.sh" missing=$((missing + 1)) continue fi - expected_hash=$(grep "\"$critical_file\"" "$MANIFEST_FILE" 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/' || echo "") if [ -z "$expected_hash" ]; then finding "WARN" "$critical_file not in manifest" "Run deploy.sh to regenerate" continue diff --git a/bin/security-audit.test.sh b/bin/security-audit.test.sh index b83aef8..f2aac5f 100644 --- a/bin/security-audit.test.sh +++ b/bin/security-audit.test.sh @@ -19,7 +19,7 @@ trap cleanup EXIT setup_base() { local home="$1" rm -rf "$home" - mkdir -p "$home/.config" "$home/.ssh" "$home/.pi" "$home/opt/baudbot/current/slack-bridge" "$home/baudbot/.git" + mkdir -p "$home/.config" "$home/.ssh" "$home/.pi" "$home/opt/baudbot/current/gateway-bridge" "$home/baudbot/.git" # Secrets file echo "SLACK_BOT_TOKEN=xoxb-test" > "$home/.config/.env" @@ -38,8 +38,8 @@ setup_base() { echo -e "[user]\n\tname = test\n\temail = test@test.com" > "$home/.gitconfig" # Bridge security module - echo "// security" > "$home/opt/baudbot/current/slack-bridge/security.mjs" - echo "// tests" > "$home/opt/baudbot/current/slack-bridge/security.test.mjs" + echo "// security" > "$home/opt/baudbot/current/gateway-bridge/security.mjs" + echo "// tests" > "$home/opt/baudbot/current/gateway-bridge/security.test.mjs" # Audit log (fallback location) mkdir -p "$home/logs" @@ -183,7 +183,7 @@ echo "" echo "Test: missing bridge security module" HOME8="$TMPDIR/no-bridge-sec" setup_base "$HOME8" -rm -f "$HOME8/opt/baudbot/current/slack-bridge/security.mjs" +rm -f "$HOME8/opt/baudbot/current/gateway-bridge/security.mjs" output=$(run_audit "$HOME8") expect_contains "reports missing security module" "$output" "Bridge security module not found" @@ -195,7 +195,7 @@ echo "" echo "Test: missing bridge tests" HOME9="$TMPDIR/no-bridge-tests" setup_base "$HOME9" -rm -f "$HOME9/opt/baudbot/current/slack-bridge/security.test.mjs" +rm -f "$HOME9/opt/baudbot/current/gateway-bridge/security.test.mjs" output=$(run_audit "$HOME9") expect_contains "reports missing tests" "$output" "No tests for bridge security" diff --git a/bin/test.sh b/bin/test.sh index 3923a93..bbb7f78 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -49,8 +49,8 @@ JS_TEST_FILES=( pi/extensions/tool-guard.test.mjs pi/extensions/heartbeat.test.mjs pi/extensions/memory.test.mjs - slack-bridge/security.test.mjs - slack-bridge/env-aliases.test.mjs + gateway-bridge/security.test.mjs + gateway-bridge/env-aliases.test.mjs bin/scan-extensions.test.mjs bin/broker-register.test.mjs ) diff --git a/bin/update-release.sh b/bin/update-release.sh index 90a03d1..7ed6ed9 100755 --- a/bin/update-release.sh +++ b/bin/update-release.sh @@ -258,14 +258,18 @@ EOF install_release_bridge_dependencies() { local release_dir="$1" - local bridge_dir="$release_dir/slack-bridge" + local bridge_dir="$release_dir/gateway-bridge" if [ ! -d "$bridge_dir" ] || [ ! -f "$bridge_dir/package.json" ]; then - log "slack-bridge package.json missing; skipping bridge dependency install" + bridge_dir="$release_dir/slack-bridge" + fi + + if [ ! -d "$bridge_dir" ] || [ ! -f "$bridge_dir/package.json" ]; then + log "gateway-bridge/slack-bridge package.json missing; skipping bridge dependency install" return 0 fi - log "installing production Gateway bridge dependencies in release" + log "installing production Gateway bridge dependencies in release ($bridge_dir)" rm -rf "$bridge_dir/node_modules" # Resolve npm via the embedded Node runtime. update-release runs as root diff --git a/bin/verify-manifest.test.sh b/bin/verify-manifest.test.sh index cff4e32..b860b1a 100755 --- a/bin/verify-manifest.test.sh +++ b/bin/verify-manifest.test.sh @@ -43,7 +43,7 @@ make_manifest() { local ext_file="$home_dir/.pi/agent/extensions/test.ts" local runtime_file="$home_dir/runtime/bin/helper.sh" - local bridge_file="$release_dir/slack-bridge/bridge.mjs" + local bridge_file="$release_dir/gateway-bridge/bridge.mjs" local log_file="$home_dir/.pi/agent/logs/bridge.log" cat >"$manifest_file" < "$HOME1/.pi/agent/extensions/test.ts" printf '#!/bin/bash\necho helper\n' > "$HOME1/runtime/bin/helper.sh" -printf 'export const bridge = true;\n' > "$RELEASE1/slack-bridge/bridge.mjs" +printf 'export const bridge = true;\n' > "$RELEASE1/gateway-bridge/bridge.mjs" printf 'mutable log\n' > "$HOME1/.pi/agent/logs/bridge.log" MANIFEST1="$HOME1/.pi/agent/baudbot-manifest.json" diff --git a/biome.json b/biome.json index cc1223f..2164f62 100644 --- a/biome.json +++ b/biome.json @@ -5,7 +5,7 @@ "bin/**/*.mjs", "pi/extensions/**/*.ts", "pi/extensions/**/*.mjs", - "slack-bridge/**/*.mjs" + "gateway-bridge/**/*.mjs" ] }, "linter": { diff --git a/slack-bridge/AGENTS.md b/gateway-bridge/AGENTS.md similarity index 84% rename from slack-bridge/AGENTS.md rename to gateway-bridge/AGENTS.md index 4515e24..6d252e7 100644 --- a/slack-bridge/AGENTS.md +++ b/gateway-bridge/AGENTS.md @@ -1,6 +1,6 @@ -# slack-bridge/ (Gateway bridge) — Agent Guidelines +# gateway-bridge/ — Agent Guidelines -Scope: Gateway bridge runtime and security modules under `slack-bridge/`. +Scope: Gateway bridge runtime and security modules under `gateway-bridge/` (legacy shim: `slack-bridge/`). ## Focus areas diff --git a/slack-bridge/bridge.mjs b/gateway-bridge/bridge.mjs similarity index 100% rename from slack-bridge/bridge.mjs rename to gateway-bridge/bridge.mjs diff --git a/slack-bridge/broker-bridge.mjs b/gateway-bridge/broker-bridge.mjs similarity index 100% rename from slack-bridge/broker-bridge.mjs rename to gateway-bridge/broker-bridge.mjs diff --git a/slack-bridge/crypto.mjs b/gateway-bridge/crypto.mjs similarity index 100% rename from slack-bridge/crypto.mjs rename to gateway-bridge/crypto.mjs diff --git a/slack-bridge/crypto.test.mjs b/gateway-bridge/crypto.test.mjs similarity index 100% rename from slack-bridge/crypto.test.mjs rename to gateway-bridge/crypto.test.mjs diff --git a/slack-bridge/env-aliases.mjs b/gateway-bridge/env-aliases.mjs similarity index 100% rename from slack-bridge/env-aliases.mjs rename to gateway-bridge/env-aliases.mjs diff --git a/slack-bridge/env-aliases.test.mjs b/gateway-bridge/env-aliases.test.mjs similarity index 100% rename from slack-bridge/env-aliases.test.mjs rename to gateway-bridge/env-aliases.test.mjs diff --git a/slack-bridge/github-events.mjs b/gateway-bridge/github-events.mjs similarity index 100% rename from slack-bridge/github-events.mjs rename to gateway-bridge/github-events.mjs diff --git a/slack-bridge/github-events.test.mjs b/gateway-bridge/github-events.test.mjs similarity index 100% rename from slack-bridge/github-events.test.mjs rename to gateway-bridge/github-events.test.mjs diff --git a/slack-bridge/package-lock.json b/gateway-bridge/package-lock.json similarity index 99% rename from slack-bridge/package-lock.json rename to gateway-bridge/package-lock.json index ac3b260..c110d76 100644 --- a/slack-bridge/package-lock.json +++ b/gateway-bridge/package-lock.json @@ -1,11 +1,11 @@ { - "name": "slack-bridge", + "name": "gateway-bridge", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "slack-bridge", + "name": "gateway-bridge", "version": "1.0.0", "dependencies": { "@slack/bolt": "^4.6.0", diff --git a/slack-bridge/package.json b/gateway-bridge/package.json similarity index 92% rename from slack-bridge/package.json rename to gateway-bridge/package.json index cc55226..576d49c 100644 --- a/slack-bridge/package.json +++ b/gateway-bridge/package.json @@ -1,5 +1,5 @@ { - "name": "slack-bridge", + "name": "gateway-bridge", "version": "1.0.0", "description": "Gateway bridge runtimes (Socket Mode + broker pull mode)", "main": "bridge.mjs", diff --git a/slack-bridge/security.mjs b/gateway-bridge/security.mjs similarity index 100% rename from slack-bridge/security.mjs rename to gateway-bridge/security.mjs diff --git a/slack-bridge/security.test.mjs b/gateway-bridge/security.test.mjs similarity index 100% rename from slack-bridge/security.test.mjs rename to gateway-bridge/security.test.mjs diff --git a/hooks/pre-commit b/hooks/pre-commit index 8b97b84..a3128be 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -9,13 +9,13 @@ # The agent can freely modify: # - pi/skills/ (operational knowledge) # - pi/extensions/ (non-security extensions like zen-provider.ts, auto-name.ts, etc.) -# - slack-bridge/bridge.mjs (non-security bridge code) +# - gateway-bridge/bridge.mjs (non-security bridge code) # - README.md, .gitignore, etc. # # The agent CANNOT modify (blocked by this hook): # - bin/ (security scripts: tool deny lists, firewall, audit, hardening) # - pi/extensions/tool-guard.ts (and its tests) -# - slack-bridge/security.mjs (and its tests) +# - gateway-bridge/security.mjs (and its tests) # - SECURITY.md # - setup.sh # - start.sh @@ -34,6 +34,9 @@ PROTECTED_PREFIXES=( PROTECTED_FILES=( "pi/extensions/tool-guard.ts" "pi/extensions/tool-guard.test.mjs" + "gateway-bridge/security.mjs" + "gateway-bridge/security.test.mjs" + # Legacy compat path (symlink) "slack-bridge/security.mjs" "slack-bridge/security.test.mjs" ) diff --git a/pi/extensions/heartbeat.ts b/pi/extensions/heartbeat.ts index 8180dfa..4c53177 100644 --- a/pi/extensions/heartbeat.ts +++ b/pi/extensions/heartbeat.ts @@ -39,7 +39,8 @@ const SOCKET_DIR = join(homedir(), ".pi", "session-control"); const WORKTREES_DIR = join(homedir(), "workspace", "worktrees"); const TODOS_DIR = join(homedir(), ".pi", "todos"); const BRIDGE_URL = "http://127.0.0.1:7890/send"; -const BRIDGE_LOG = join(homedir(), ".pi", "agent", "logs", "slack-bridge.log"); +const BRIDGE_LOG_PRIMARY = join(homedir(), ".pi", "agent", "logs", "gateway-bridge.log"); +const BRIDGE_LOG_LEGACY = join(homedir(), ".pi", "agent", "logs", "slack-bridge.log"); const SESSION_DIR = join(homedir(), ".pi", "agent", "sessions"); const UNANSWERED_MENTION_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes @@ -83,6 +84,12 @@ function isUnansweredMentionsCheckEnabled(): boolean { return val !== "0" && val !== "false" && val !== "no"; } +function resolveBridgeLogPath(): string | null { + if (existsSync(BRIDGE_LOG_PRIMARY)) return BRIDGE_LOG_PRIMARY; + if (existsSync(BRIDGE_LOG_LEGACY)) return BRIDGE_LOG_LEGACY; + return null; +} + // ── Health Check Functions ────────────────────────────────────────────────── function checkSessions(): CheckResult[] { @@ -314,8 +321,9 @@ function checkStuckTodos(): CheckResult[] { function checkUnansweredMentions(): CheckResult[] { const results: CheckResult[] = []; const now = Date.now(); + const bridgeLogPath = resolveBridgeLogPath(); - if (!existsSync(BRIDGE_LOG)) return results; + if (!bridgeLogPath) return results; try { // Read the last 500 lines of the bridge log to find recent app_mention events. @@ -323,7 +331,7 @@ function checkUnansweredMentions(): CheckResult[] { // - broker-bridge.mjs: "... (type: app_mention, ts: 1234.5678)" // - bridge.mjs: "app_mention ... ts: 1234.5678" const { execSync } = require("node:child_process"); - const logTail = execSync(`tail -500 "${BRIDGE_LOG}"`, { encoding: "utf-8" }); + const logTail = execSync(`tail -500 "${bridgeLogPath}"`, { encoding: "utf-8" }); const mentionThreadTsSet = new Set(extractMentionThreadTs(logTail)); @@ -792,7 +800,8 @@ export default function heartbeatExtension(pi: ExtensionAPI): void { ` Unanswered mention threshold: ${UNANSWERED_MENTION_THRESHOLD_MS / (60 * 1000)} min`, ` Stuck todo threshold: ${STUCK_TODO_THRESHOLD_MS / (60 * 60 * 1000)}h`, ` Bridge URL: ${BRIDGE_URL}`, - ` Bridge log: ${BRIDGE_LOG}`, + ` Bridge log (primary): ${BRIDGE_LOG_PRIMARY}`, + ` Bridge log (legacy fallback): ${BRIDGE_LOG_LEGACY}`, ` Socket dir: ${SOCKET_DIR}`, ` Worktrees dir: ${WORKTREES_DIR}`, ` Todos dir: ${TODOS_DIR}`, diff --git a/pi/extensions/tool-guard.test.mjs b/pi/extensions/tool-guard.test.mjs index fbe6121..6110f92 100644 --- a/pi/extensions/tool-guard.test.mjs +++ b/pi/extensions/tool-guard.test.mjs @@ -46,7 +46,7 @@ const BASH_DENY_RULES = [ { id: "chmod-baudbot-source", pattern: new RegExp(`chmod\\b.*${escapeRegex(BAUDBOT_SOURCE_DIR)}`), label: "chmod on baudbot source repo", severity: "block" }, { id: "chown-baudbot-source", pattern: new RegExp(`chown\\b.*${escapeRegex(BAUDBOT_SOURCE_DIR)}`), label: "chown on baudbot source repo", severity: "block" }, { id: "tee-baudbot-source", pattern: new RegExp(`tee\\s+.*${escapeRegex(BAUDBOT_SOURCE_DIR)}/`), label: "tee write to baudbot source repo", severity: "block" }, - { id: "chmod-runtime-security", pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/slack-bridge\/security|opt\/baudbot\/current\/slack-bridge\/security)\./, label: "chmod on protected runtime security file", severity: "block" }, + { id: "chmod-runtime-security", pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/(?:gateway|slack)-bridge\/security|opt\/baudbot\/current\/(?:gateway|slack)-bridge\/security)\./, label: "chmod on protected runtime security file", severity: "block" }, // Credential exfiltration { id: "env-exfil-curl", pattern: /\benv\b.*\|\s*(curl|wget|nc)\b/, label: "Piping environment to network tool", severity: "block" }, { id: "cat-env-curl", pattern: /cat\s+.*\.env.*\|\s*(curl|wget|nc)\b/, label: "Exfiltrating .env via network", severity: "block" }, @@ -77,6 +77,9 @@ function isAllowedWritePath(filePath) { const PROTECTED_RUNTIME_FILES = [ `${AGENT_HOME}/.pi/agent/extensions/tool-guard.ts`, `${AGENT_HOME}/.pi/agent/extensions/tool-guard.test.mjs`, + `/opt/baudbot/current/gateway-bridge/security.mjs`, + `/opt/baudbot/current/gateway-bridge/security.test.mjs`, + // Legacy compat path `/opt/baudbot/current/slack-bridge/security.mjs`, `/opt/baudbot/current/slack-bridge/security.test.mjs`, ]; @@ -307,6 +310,9 @@ describe("tool-guard: source repo protection (bash)", () => { assert.equal(checkBashCommand(`chmod a+w ${AGENT_HOME}/.pi/agent/extensions/tool-guard.ts`).blocked, true); }); it("blocks chmod on runtime security.mjs", () => { + assert.equal(checkBashCommand("chmod 777 /opt/baudbot/current/gateway-bridge/security.mjs").blocked, true); + }); + it("blocks chmod on runtime security.mjs via legacy path", () => { assert.equal(checkBashCommand("chmod 777 /opt/baudbot/current/slack-bridge/security.mjs").blocked, true); }); }); @@ -358,8 +364,8 @@ describe("tool-guard: workspace confinement (allow-list)", () => { it(`allows write to ${AGENT_HOME}/.pi/agent/skills/new-skill/SKILL.md`, () => { assert.equal(checkWritePath(`${AGENT_HOME}/.pi/agent/skills/new-skill/SKILL.md`), false); }); - it("blocks write to /opt/baudbot/current/slack-bridge/bridge.mjs", () => { - assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/bridge.mjs"), true); + it("blocks write to /opt/baudbot/current/gateway-bridge/bridge.mjs", () => { + assert.equal(checkWritePath("/opt/baudbot/current/gateway-bridge/bridge.mjs"), true); }); // BLOCKED: outside agent home @@ -418,6 +424,9 @@ describe("tool-guard: source repo is fully read-only (write/edit)", () => { assert.equal(checkWritePath(`${BAUDBOT_SOURCE_DIR}/.git/hooks/pre-commit`), true); }); it("blocks write to source repo bridge", () => { + assert.equal(checkWritePath(`${BAUDBOT_SOURCE_DIR}/gateway-bridge/bridge.mjs`), true); + }); + it("blocks write to source repo bridge via legacy shim path", () => { assert.equal(checkWritePath(`${BAUDBOT_SOURCE_DIR}/slack-bridge/bridge.mjs`), true); }); }); @@ -430,12 +439,21 @@ describe("tool-guard: protected runtime security files", () => { assert.equal(checkWritePath(`${AGENT_HOME}/.pi/agent/extensions/tool-guard.test.mjs`), true); }); it("blocks write to runtime security.mjs", () => { + assert.equal(checkWritePath("/opt/baudbot/current/gateway-bridge/security.mjs"), true); + }); + it("blocks write to runtime security.mjs via legacy path", () => { assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/security.mjs"), true); }); it("blocks write to runtime security.test.mjs", () => { + assert.equal(checkWritePath("/opt/baudbot/current/gateway-bridge/security.test.mjs"), true); + }); + it("blocks write to runtime security.test.mjs via legacy path", () => { assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/security.test.mjs"), true); }); it("blocks write to runtime bridge.mjs (immutable release path)", () => { + assert.equal(checkWritePath("/opt/baudbot/current/gateway-bridge/bridge.mjs"), true); + }); + it("blocks write to runtime bridge.mjs via legacy path", () => { assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/bridge.mjs"), true); }); it("allows write to runtime non-security extensions", () => { diff --git a/pi/extensions/tool-guard.ts b/pi/extensions/tool-guard.ts index cf8af78..e150013 100644 --- a/pi/extensions/tool-guard.ts +++ b/pi/extensions/tool-guard.ts @@ -253,7 +253,7 @@ const BASH_DENY_RULES: DenyRule[] = [ ] : []), { id: "chmod-runtime-security", - pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/slack-bridge\/security|opt\/baudbot\/current\/slack-bridge\/security)\./, + pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/(?:gateway|slack)-bridge\/security|opt\/baudbot\/current\/(?:gateway|slack)-bridge\/security)\./, label: "chmod on protected runtime security file", severity: "block" as const, tier: "high" as const, @@ -311,6 +311,9 @@ function isAllowedWritePath(filePath: string): boolean { const PROTECTED_RUNTIME_FILES = [ `${AGENT_HOME}/.pi/agent/extensions/tool-guard.ts`, `${AGENT_HOME}/.pi/agent/extensions/tool-guard.test.mjs`, + `/opt/baudbot/current/gateway-bridge/security.mjs`, + `/opt/baudbot/current/gateway-bridge/security.test.mjs`, + // Legacy compat path `/opt/baudbot/current/slack-bridge/security.mjs`, `/opt/baudbot/current/slack-bridge/security.test.mjs`, ]; diff --git a/pi/skills/control-agent/SKILL.md b/pi/skills/control-agent/SKILL.md index 705accd..9532619 100644 --- a/pi/skills/control-agent/SKILL.md +++ b/pi/skills/control-agent/SKILL.md @@ -24,7 +24,7 @@ You **can** update your own skills (`pi/skills/`) and non-security extensions. C You **cannot** modify these protected files (enforced by file ownership, tool-guard, and pre-commit hook): - `bin/`, `hooks/`, `setup.sh`, `start.sh`, `SECURITY.md` - `pi/extensions/tool-guard.ts` (and its tests) -- `slack-bridge/security.mjs` (and its tests) +- `gateway-bridge/security.mjs` (and its tests; legacy shim path: `slack-bridge/security.mjs`) Do NOT attempt to fix permissions on protected files. If you need changes, report to the admin. @@ -351,8 +351,11 @@ The `startup-pi.sh` script handles bridge (re)start automatically — it detects If you need to restart the bridge manually, rerun startup cleanup and then inspect logs: ```bash bash ~/.pi/agent/skills/control-agent/startup-pi.sh UUID1 UUID2 UUID3 -tail -n 200 ~/.pi/agent/logs/slack-bridge.log -cat ~/.pi/agent/slack-bridge-supervisor.json +tail -n 200 ~/.pi/agent/logs/gateway-bridge.log +cat ~/.pi/agent/gateway-bridge-supervisor.json +# Legacy fallback paths (during migration): +# tail -n 200 ~/.pi/agent/logs/slack-bridge.log +# cat ~/.pi/agent/slack-bridge-supervisor.json ``` Verify: `curl -s -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:7890/send -H 'Content-Type: application/json' -d '{}'` → should return `400`. @@ -370,7 +373,7 @@ If you need to check manually, use `heartbeat trigger` to run all checks immedia When the heartbeat reports a failure, take the appropriate action: 1. **Missing sentry-agent**: Respawn with `agent_spawn` and re-send role assignment. 2. **Orphaned dev-agents**: Kill tmux session and remove worktree. -3. **Bridge down**: Restart via `startup-pi.sh`, then check `~/.pi/agent/logs/slack-bridge.log`. +3. **Bridge down**: Restart via `startup-pi.sh`, then check `~/.pi/agent/logs/gateway-bridge.log` (fallback: `~/.pi/agent/logs/slack-bridge.log`). 4. **Stale worktrees**: `git worktree remove --force` + `rmdir` empty parents. 5. **Stuck todos**: Escalate to user via Slack. diff --git a/pi/skills/control-agent/startup-pi.sh b/pi/skills/control-agent/startup-pi.sh index 0f2f0c1..091ef23 100755 --- a/pi/skills/control-agent/startup-pi.sh +++ b/pi/skills/control-agent/startup-pi.sh @@ -10,7 +10,8 @@ # Pass the live session UUIDs (from list_sessions) as arguments. # Any .sock file whose UUID is NOT in the live set gets removed. # Stale .alias symlinks pointing to removed sockets also get cleaned. -# Then starts the Gateway bridge process (from slack-bridge/) with the current control-agent UUID. +# Then starts the Gateway bridge process (from gateway-bridge/, with legacy +# slack-bridge/ shim support) with the current control-agent UUID. # # Process lifecycle is managed via process groups (see runtime/start.sh). # When start.sh kills the old control-agent PGID, all spawned services @@ -84,12 +85,26 @@ else fi BRIDGE_LOG_DIR="$HOME/.pi/agent/logs" -BRIDGE_LOG_FILE="$BRIDGE_LOG_DIR/slack-bridge.log" -BRIDGE_DIR="/opt/baudbot/current/slack-bridge" -BRIDGE_TMUX_SESSION="baudbot-slack-bridge" +BRIDGE_LOG_FILE="$BRIDGE_LOG_DIR/gateway-bridge.log" +LEGACY_BRIDGE_LOG_FILE="$BRIDGE_LOG_DIR/slack-bridge.log" +BRIDGE_DIR="/opt/baudbot/current/gateway-bridge" +BRIDGE_DIR_LEGACY="/opt/baudbot/current/slack-bridge" +BRIDGE_TMUX_SESSION="baudbot-gateway-bridge" mkdir -p "$BRIDGE_LOG_DIR" +# Migrate legacy bridge log to new filename and keep a compat symlink. +if [ -f "$LEGACY_BRIDGE_LOG_FILE" ] && [ ! -e "$BRIDGE_LOG_FILE" ]; then + mv "$LEGACY_BRIDGE_LOG_FILE" "$BRIDGE_LOG_FILE" +fi +if [ "$LEGACY_BRIDGE_LOG_FILE" != "$BRIDGE_LOG_FILE" ]; then + ln -sfn "$(basename "$BRIDGE_LOG_FILE")" "$LEGACY_BRIDGE_LOG_FILE" 2>/dev/null || true +fi + +if [ ! -d "$BRIDGE_DIR" ] && [ -d "$BRIDGE_DIR_LEGACY" ]; then + BRIDGE_DIR="$BRIDGE_DIR_LEGACY" +fi + # --- Detect bridge mode --- BRIDGE_SCRIPT="" if [ -f "$BRIDGE_DIR/broker-bridge.mjs" ] && varlock run --path "$HOME/.config/" -- sh -c ' @@ -137,7 +152,7 @@ if [ -n "$AGENT_SESSIONS" ]; then sleep 1 fi -echo "Starting Gateway bridge (slack-bridge/$BRIDGE_SCRIPT) via tmux..." +echo "Starting Gateway bridge ($(basename "$BRIDGE_DIR")/$BRIDGE_SCRIPT) via tmux..." NODE_BIN_DIR="${NODE_BIN_DIR:-$HOME/opt/node/bin}" if command -v bb_resolve_runtime_node_bin_dir >/dev/null 2>&1; then NODE_BIN_DIR="$(bb_resolve_runtime_node_bin_dir "$HOME")" diff --git a/pi/skills/debug-agent/SKILL.md b/pi/skills/debug-agent/SKILL.md index 4e0e350..c62fc25 100644 --- a/pi/skills/debug-agent/SKILL.md +++ b/pi/skills/debug-agent/SKILL.md @@ -25,7 +25,7 @@ The activity feed tails the control-agent's session JSONL file — it updates au ## What you can do -- **Read logs**: `~/.pi/agent/logs/slack-bridge.log`, `journalctl -u baudbot` +- **Read logs**: `~/.pi/agent/logs/gateway-bridge.log` (legacy fallback: `~/.pi/agent/logs/slack-bridge.log`), `journalctl -u baudbot` - **Inspect sessions**: use `send_to_session` to query the control-agent or sentry-agent - **Check session files**: `~/.pi/agent/sessions/` contains full conversation history as JSONL - **Review todos**: use the `todo` tool to see work items @@ -43,8 +43,8 @@ The activity feed tails the control-agent's session JSONL file — it updates au | What | Where | |------|-------| | Control-agent socket | `~/.pi/session-control/control-agent.alias` | -| Bridge logs | `~/.pi/agent/logs/slack-bridge.log` | -| Bridge tmux | `tmux attach -t slack-bridge` | +| Bridge logs | `~/.pi/agent/logs/gateway-bridge.log` (legacy: `~/.pi/agent/logs/slack-bridge.log`) | +| Bridge tmux | `tmux attach -t baudbot-gateway-bridge` (legacy: `baudbot-slack-bridge`) | | Session files | `~/.pi/agent/sessions/--home-baudbot_agent--/` | | Todos | `~/.pi/todos/` | | Deploy dir | `/opt/baudbot/current` → releases/SHA | diff --git a/pi/skills/dev-agent/SKILL.md b/pi/skills/dev-agent/SKILL.md index af87068..9c35dae 100644 --- a/pi/skills/dev-agent/SKILL.md +++ b/pi/skills/dev-agent/SKILL.md @@ -44,7 +44,7 @@ You **can** modify: `~/scripts/`, `~/workspace/baudbot/pi/skills/`, non-security You **cannot** modify protected files (enforced by file ownership, tool-guard, and pre-commit hook): - `bin/`, `hooks/`, `setup.sh`, `start.sh`, `SECURITY.md` -- `pi/extensions/tool-guard.ts`, `slack-bridge/security.mjs` (and their tests) +- `pi/extensions/tool-guard.ts`, `gateway-bridge/security.mjs` (and their tests; legacy shim path: `slack-bridge/security.mjs`) ## Memory diff --git a/setup.sh b/setup.sh index d49923f..154eec5 100755 --- a/setup.sh +++ b/setup.sh @@ -246,7 +246,7 @@ while IFS= read -r dir; do done < <(find "$REPO_DIR/pi/extensions" -name package.json -not -path '*/node_modules/*' -exec dirname {} \;) echo "=== Installing Gateway bridge dependencies ===" -(cd "$REPO_DIR/slack-bridge" && npm install) +(cd "$REPO_DIR/gateway-bridge" && npm install) echo "=== Installing varlock ===" # varlock must be available to the agent user (start.sh adds ~/.varlock/bin to PATH). diff --git a/slack-bridge b/slack-bridge new file mode 120000 index 0000000..00cf1c6 --- /dev/null +++ b/slack-bridge @@ -0,0 +1 @@ +gateway-bridge \ No newline at end of file diff --git a/start.sh b/start.sh index 893a091..90576c2 100755 --- a/start.sh +++ b/start.sh @@ -5,7 +5,7 @@ # The agent runs entirely from deployed copies — no source repo access needed: # ~/.pi/agent/extensions/ ← pi extensions # ~/.pi/agent/skills/ ← operational skills -# /opt/baudbot/current/slack-bridge/ ← bridge process +# /opt/baudbot/current/gateway-bridge/ ← bridge process (legacy shim: /opt/baudbot/current/slack-bridge/) # ~/runtime/bin/ ← utility scripts # # To update, admin edits source and runs deploy.sh. diff --git a/test/broker-bridge.integration.test.mjs b/test/broker-bridge.integration.test.mjs index 3f7c0c6..60d7a57 100644 --- a/test/broker-bridge.integration.test.mjs +++ b/test/broker-bridge.integration.test.mjs @@ -10,7 +10,7 @@ import sodium from "libsodium-wrappers-sumo"; import { canonicalizeEnvelope, canonicalizeProtocolRequest, -} from "../slack-bridge/crypto.mjs"; +} from "../gateway-bridge/crypto.mjs"; function b64(bytes = 32, fill = 1) { return Buffer.alloc(bytes, fill).toString("base64"); @@ -120,8 +120,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); let bridgeStdout = ""; let bridgeStderr = ""; @@ -240,8 +240,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); let bridgeStdout = ""; let bridgeStderr = ""; @@ -378,8 +378,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); let bridgeStdout = ""; let bridgeStderr = ""; @@ -446,8 +446,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const tempHome = mkdtempSync(path.join(tmpdir(), "baudbot-broker-test-")); tempDirs.push(tempHome); @@ -698,8 +698,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const bridge = spawn("node", [bridgePath], { cwd: bridgeCwd, @@ -803,8 +803,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const bridge = spawn("node", [bridgePath], { cwd: bridgeCwd, @@ -891,8 +891,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const bridge = spawn("node", [bridgePath], { cwd: bridgeCwd, @@ -975,8 +975,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const bridge = spawn("node", [bridgePath], { cwd: bridgeCwd, @@ -1026,8 +1026,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); let bridgeStdout = ""; let bridgeStderr = ""; @@ -1074,8 +1074,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); let bridgeStdout = ""; let bridgeStderr = ""; @@ -1121,8 +1121,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const tempHome = mkdtempSync(path.join(tmpdir(), "baudbot-broker-test-")); tempDirs.push(tempHome); @@ -1306,8 +1306,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const serverBox = sodium.crypto_box_keypair(); const brokerBox = sodium.crypto_box_keypair(); @@ -1446,8 +1446,8 @@ describe("broker pull bridge semi-integration", () => { const testFileDir = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.dirname(testFileDir); - const bridgePath = path.join(repoRoot, "slack-bridge", "broker-bridge.mjs"); - const bridgeCwd = path.join(repoRoot, "slack-bridge"); + const bridgePath = path.join(repoRoot, "gateway-bridge", "broker-bridge.mjs"); + const bridgeCwd = path.join(repoRoot, "gateway-bridge"); const serverBox = sodium.crypto_box_keypair(); const brokerBox = sodium.crypto_box_keypair(); diff --git a/test/github-events.test.mjs b/test/github-events.test.mjs index 1a4031e..9c65fd1 100644 --- a/test/github-events.test.mjs +++ b/test/github-events.test.mjs @@ -20,6 +20,6 @@ function runNodeTest(relativePath) { describe("github-events node:test suite", () => { it("github-events", () => { - expect(() => runNodeTest("slack-bridge/github-events.test.mjs")).not.toThrow(); + expect(() => runNodeTest("gateway-bridge/github-events.test.mjs")).not.toThrow(); }); }); diff --git a/test/legacy-node-tests.test.mjs b/test/legacy-node-tests.test.mjs index a96d5ae..452c603 100644 --- a/test/legacy-node-tests.test.mjs +++ b/test/legacy-node-tests.test.mjs @@ -24,11 +24,11 @@ describe("legacy node:test suites", () => { }); it("bridge security", () => { - expect(() => runNodeTest("slack-bridge/security.test.mjs")).not.toThrow(); + expect(() => runNodeTest("gateway-bridge/security.test.mjs")).not.toThrow(); }); it("gateway env aliases", () => { - expect(() => runNodeTest("slack-bridge/env-aliases.test.mjs")).not.toThrow(); + expect(() => runNodeTest("gateway-bridge/env-aliases.test.mjs")).not.toThrow(); }); it("extension scanner", () => { diff --git a/test/security-audit.test.mjs b/test/security-audit.test.mjs index b927bcd..7a4c61a 100644 --- a/test/security-audit.test.mjs +++ b/test/security-audit.test.mjs @@ -13,7 +13,7 @@ function setupFixture(homeDir) { fs.mkdirSync(path.join(homeDir, ".config"), { recursive: true }); fs.mkdirSync(path.join(homeDir, ".ssh"), { recursive: true }); fs.mkdirSync(path.join(homeDir, ".pi/agent"), { recursive: true }); - fs.mkdirSync(path.join(homeDir, "opt/baudbot/current/slack-bridge"), { recursive: true }); + fs.mkdirSync(path.join(homeDir, "opt/baudbot/current/gateway-bridge"), { recursive: true }); fs.mkdirSync(path.join(homeDir, "baudbot/.git/hooks"), { recursive: true }); fs.mkdirSync(path.join(homeDir, "logs"), { recursive: true }); @@ -29,8 +29,8 @@ function setupFixture(homeDir) { path.join(homeDir, ".pi/agent/baudbot-version.json"), JSON.stringify({ short: "testsha", deployed_at: "2026-01-01T00:00:00Z" }), ); - fs.writeFileSync(path.join(homeDir, "opt/baudbot/current/slack-bridge/security.mjs"), "// security\n"); - fs.writeFileSync(path.join(homeDir, "opt/baudbot/current/slack-bridge/security.test.mjs"), "// tests\n"); + fs.writeFileSync(path.join(homeDir, "opt/baudbot/current/gateway-bridge/security.mjs"), "// security\n"); + fs.writeFileSync(path.join(homeDir, "opt/baudbot/current/gateway-bridge/security.test.mjs"), "// tests\n"); fs.writeFileSync(path.join(homeDir, "logs/commands.log"), ""); }