summaryrefslogtreecommitdiffhomepage
path: root/bin
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-04 21:21:20 +0900
committerAdam Malczewski <[email protected]>2026-06-04 21:21:20 +0900
commit394f1ed37ce860da6fdc385769bf29f9737105cd (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /bin
parent81a9cdbadf8c9d940d4fe9a2a0de607dee1f5f1a (diff)
downloaddispatch-394f1ed37ce860da6fdc385769bf29f9737105cd.tar.gz
dispatch-394f1ed37ce860da6fdc385769bf29f9737105cd.zip
chore: genesis — remove all files to rebuild from scratch (arch rewrite)
Diffstat (limited to 'bin')
-rwxr-xr-xbin/build7
-rwxr-xr-xbin/build-frontend17
-rwxr-xr-xbin/build-pkg28
-rwxr-xr-xbin/build-pkg-electron20
-rwxr-xr-xbin/build-pkg-windows38
-rwxr-xr-xbin/clean9
-rwxr-xr-xbin/copilot-auth84
-rwxr-xr-xbin/dev_secrets27
-rwxr-xr-xbin/down7
-rwxr-xr-xbin/import-credentials.ts34
-rwxr-xr-xbin/install-pkg76
-rwxr-xr-xbin/prod_secrets33
-rw-r--r--bin/seed-opencode-keys.ts28
-rwxr-xr-xbin/service105
-rwxr-xr-xbin/test10
-rwxr-xr-xbin/up79
-rwxr-xr-xbin/up-backend21
-rwxr-xr-xbin/up-frontend8
18 files changed, 0 insertions, 631 deletions
diff --git a/bin/build b/bin/build
deleted file mode 100755
index cd0dabb..0000000
--- a/bin/build
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-docker compose -f "$PROJECT_DIR/docker-compose.yml" build "$@"
diff --git a/bin/build-frontend b/bin/build-frontend
deleted file mode 100755
index 703e072..0000000
--- a/bin/build-frontend
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Build frontend assets inside a temporary container
-# Output lands in packages/frontend/dist/ on the host (via bind mount)
-#
-# VITE_API_URL can be set to configure the API endpoint for the build.
-# Example: VITE_API_URL=https://api.example.com bin/build-frontend
-
-sudo VITE_API_URL="${VITE_API_URL:-}" \
- docker compose -f "$PROJECT_DIR/docker-compose.yml" \
- run --rm \
- -e VITE_API_URL \
- frontend bun run --cwd packages/frontend build "$@"
diff --git a/bin/build-pkg b/bin/build-pkg
deleted file mode 100755
index f8bc8b2..0000000
--- a/bin/build-pkg
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env bash
-# Build the dispatch Arch split package: dispatch + dispatch-systemd + dispatch-s6.
-# One makepkg run produces three .pkg.tar.zst files in packaging/.
-#
-# Usage:
-# bin/build-pkg # build
-# bin/build-pkg --noconfirm # forward extra args to makepkg
-#
-# Override frontend build target with VITE_API_URL, e.g.:
-# VITE_API_URL="https://api.example.com" bin/build-pkg
-#
-# The patched `cs` code-search binary is reused from an already-installed
-# code-search package instead of being recompiled. Force a fresh clone+build
-# (required after bumping _cs_commit in the PKGBUILD) with:
-# DISPATCH_FORCE_CS_BUILD=1 bin/build-pkg
-
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-PACKAGING_DIR="$PROJECT_DIR/packaging"
-
-cd "$PACKAGING_DIR"
-makepkg -fd "$@"
-
-echo ""
-echo "Built packages (newest first):"
-ls -1t "$PACKAGING_DIR"/*.pkg.tar.zst 2>/dev/null | head -5
diff --git a/bin/build-pkg-electron b/bin/build-pkg-electron
deleted file mode 100755
index ceec321..0000000
--- a/bin/build-pkg-electron
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env bash
-# Build the dispatch-electron Arch package (Linux desktop wrapper).
-# Depends on the `dispatch` package being built/installed at the matching version.
-#
-# Usage:
-# bin/build-pkg-electron # build
-# bin/build-pkg-electron --noconfirm
-
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-PACKAGING_DIR="$PROJECT_DIR/packaging/electron"
-
-cd "$PACKAGING_DIR"
-makepkg -fd "$@"
-
-echo ""
-echo "Built package:"
-ls -1t "$PACKAGING_DIR"/*.pkg.tar.zst 2>/dev/null | head -1
diff --git a/bin/build-pkg-windows b/bin/build-pkg-windows
deleted file mode 100755
index c5760e0..0000000
--- a/bin/build-pkg-windows
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env bash
-# Build the Windows Electron output via electron-builder.
-# Produces an unpacked directory at packages/frontend/release/win-unpacked.
-#
-# Usage:
-# bin/build-pkg-windows
-#
-# Override the API URL the frontend bundle points to:
-# VITE_API_URL="http://your-host:18390" bin/build-pkg-windows
-
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-FRONTEND_DIR="$PROJECT_DIR/packages/frontend"
-VITE_API_URL="${VITE_API_URL:-http://localhost:18390}"
-
-cd "$PROJECT_DIR"
-
-# Install deps (electron + electron-builder live as frontend devDependencies)
-bun install
-
-# Build the SPA bundle, then package it for Windows (unpacked dir)
-cd "$FRONTEND_DIR"
-VITE_API_URL="$VITE_API_URL" bun run dist:win
-
-WIN_BUILD="$FRONTEND_DIR/release/win-unpacked"
-
-if [ ! -d "$WIN_BUILD" ]; then
- echo "Build failed: no win-unpacked directory found at $WIN_BUILD" >&2
- exit 1
-fi
-
-echo ""
-echo "Windows Electron build ready at:"
-echo " $WIN_BUILD"
-echo ""
-echo "Copy that folder to a Windows machine and run Dispatch.exe."
diff --git a/bin/clean b/bin/clean
deleted file mode 100755
index 76bdbe1..0000000
--- a/bin/clean
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Stop containers, remove volumes, remove images, and clear build cache
-sudo docker compose -f "$PROJECT_DIR/docker-compose.yml" down --volumes --rmi local "$@"
-sudo docker builder prune -f --filter "label=com.docker.compose.project=dispatch"
diff --git a/bin/copilot-auth b/bin/copilot-auth
deleted file mode 100755
index 28d08a1..0000000
--- a/bin/copilot-auth
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-CLIENT_ID="Ov23li8tweQw6odWQebz"
-ENV_FILE="$(cd "$(dirname "$0")/.." && pwd)/.env.dispatch"
-
-# Parse form-encoded key=value pairs
-parse() {
- local key="$1" data="$2"
- local val
- val=$(echo "$data" | sed -n "s/.*${key}=\([^&]*\).*/\1/p")
- python3 -c "import sys,urllib.parse; print(urllib.parse.unquote(sys.stdin.read().strip()))" <<< "$val"
-}
-
-echo "=== GitHub Copilot OAuth ==="
-echo ""
-
-# Step 1: Request device code
-echo "Requesting device code..."
-RESP=$(curl -s https://github.com/login/device/code \
- -d "client_id=$CLIENT_ID" \
- -d "scope=read:user")
-
-DEVICE_CODE=$(parse "device_code" "$RESP")
-
-if [ -z "$DEVICE_CODE" ]; then
- echo "Failed to get device code: $RESP"
- exit 1
-fi
-
-USER_CODE=$(parse "user_code" "$RESP")
-VERIF_URI=$(parse "verification_uri" "$RESP")
-INTERVAL=$(parse "interval" "$RESP")
-INTERVAL=${INTERVAL:-5}
-
-echo ""
-echo "Open this URL and enter the code:"
-echo " $VERIF_URI"
-echo " Code: $USER_CODE"
-echo ""
-echo "Waiting for you to authorize..."
-
-# Step 2: Poll for access token
-TOKEN=""
-ATTEMPTS=0
-while [ -z "$TOKEN" ] && [ $ATTEMPTS -lt 60 ]; do
- sleep "$INTERVAL"
- ATTEMPTS=$((ATTEMPTS + 1))
-
- TOKEN_RESP=$(curl -s https://github.com/login/oauth/access_token \
- -d "client_id=$CLIENT_ID" \
- -d "device_code=$DEVICE_CODE" \
- -d "grant_type=urn:ietf:params:oauth:grant-type:device_code")
-
- TOKEN=$(parse "access_token" "$TOKEN_RESP" || true)
- ERROR=$(parse "error" "$TOKEN_RESP" || true)
-
- if [ "$ERROR" = "authorization_pending" ]; then
- continue
- elif [ "$ERROR" = "slow_down" ]; then
- INTERVAL=$((INTERVAL + 5))
- continue
- elif [ -n "$ERROR" ]; then
- echo "Error: $ERROR"
- exit 1
- fi
-done
-
-if [ -z "$TOKEN" ]; then
- echo "Timed out waiting for authorization."
- exit 1
-fi
-
-# Step 3: Write to .env.dispatch
-mkdir -p "$(dirname "$ENV_FILE")"
-if [ -f "$ENV_FILE" ] && grep -q "^COPILOT_TOKEN=" "$ENV_FILE" 2>/dev/null; then
- sed -i "s/^COPILOT_TOKEN=.*/COPILOT_TOKEN=$TOKEN/" "$ENV_FILE"
-else
- echo "COPILOT_TOKEN=$TOKEN" >> "$ENV_FILE"
-fi
-
-echo ""
-echo "Token saved to .env.dispatch"
-echo "Ready — run: docker compose up"
diff --git a/bin/dev_secrets b/bin/dev_secrets
deleted file mode 100755
index 98af50d..0000000
--- a/bin/dev_secrets
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-# Force GPG to use terminal-based pinentry (required for SSH sessions)
-export GPG_TTY=$(tty)
-
-echo "Checking dev secrets for Dispatch..."
-echo ""
-
-# --- OpenCode Go API Key ---
-
-if gopass show -o projects/ai-api/opencode_go_key &>/dev/null; then
- echo "[ok] OpenCode Go API key exists"
-else
- echo "OpenCode Go API key not found in gopass."
- echo ""
- echo " 1. Go to https://opencode.ai/auth"
- echo " 2. Sign in and copy your API key"
- echo " 3. Paste it below"
- echo ""
- read -rp "Enter your OpenCode Go API key: " OPENCODE_KEY
- echo "$OPENCODE_KEY" | gopass insert -f projects/ai-api/opencode_go_key
- echo "[ok] OpenCode Go API key stored"
-fi
-
-echo ""
-echo "All dev secrets are configured."
diff --git a/bin/down b/bin/down
deleted file mode 100755
index 9188ca2..0000000
--- a/bin/down
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-docker compose -f "$PROJECT_DIR/docker-compose.yml" down "$@"
diff --git a/bin/import-credentials.ts b/bin/import-credentials.ts
deleted file mode 100755
index a4ea499..0000000
--- a/bin/import-credentials.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bun
-/**
- * Import Claude credentials into the Dispatch SQLite database.
- * Reads from ~/.claude/.credentials-{1,2}.json and stores them
- * for the configured keys (claude-pro, claude-max).
- */
-import { getDatabasePath, importCredentialsFromFile } from "../packages/core/src/index.js";
-
-const imports = [
- {
- keyId: "claude-pro",
- provider: "anthropic",
- file: `${process.env.HOME}/.claude/.credentials-1.json`,
- },
- {
- keyId: "claude-max",
- provider: "anthropic",
- file: `${process.env.HOME}/.claude/.credentials-2.json`,
- },
-];
-
-console.log(`Database: ${getDatabasePath()}\n`);
-
-for (const { keyId, provider, file } of imports) {
- process.stdout.write(`Importing ${keyId} from ${file} ... `);
- const result = importCredentialsFromFile(keyId, provider, file);
- if (result.success) {
- console.log("OK");
- } else {
- console.log(`FAILED: ${result.error}`);
- }
-}
-
-console.log("\nDone.");
diff --git a/bin/install-pkg b/bin/install-pkg
deleted file mode 100755
index 9af784d..0000000
--- a/bin/install-pkg
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env bash
-# Install one or more built dispatch packages with yay -U.
-#
-# Default: installs the freshest dispatch + dispatch-systemd from packaging/.
-# Pass package names (without version) to install a custom set.
-#
-# Usage:
-# bin/install-pkg # dispatch + dispatch-systemd + code-search
-# bin/install-pkg dispatch dispatch-s6 # dispatch + dispatch-s6
-# bin/install-pkg dispatch dispatch-electron # dispatch + electron wrapper
-# bin/install-pkg --all # every freshest pkg found
-
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-PACKAGING_DIR="$PROJECT_DIR/packaging"
-ELECTRON_DIR="$PROJECT_DIR/packaging/electron"
-
-# Find the most recent .pkg.tar.zst matching a package name in a given dir.
-find_pkg() {
- local name="$1" dir="$2"
- ls -t "$dir"/"$name"-[0-9]*-x86_64.pkg.tar.zst 2>/dev/null | head -1
-}
-
-# Resolve a package name to its freshest tarball, searching both dirs.
-resolve_pkg() {
- local name="$1" path
- path=$(find_pkg "$name" "$PACKAGING_DIR")
- [ -n "$path" ] || path=$(find_pkg "$name" "$ELECTRON_DIR")
- echo "$path"
-}
-
-declare -a names
-declare -a paths
-
-if [ $# -eq 0 ]; then
- names=(dispatch dispatch-systemd)
- # code-search ships a self-contained `cs` binary pinned to _cs_commit in the
- # PKGBUILD; it rarely changes. Skip reinstalling it if it's already present —
- # run `bin/install-pkg code-search` to force a reinstall (e.g. after a bump).
- if pacman -Qq code-search &>/dev/null; then
- echo "code-search already installed — skipping (run 'bin/install-pkg code-search' to force)"
- else
- names+=(code-search)
- fi
-elif [ "${1:-}" = "--all" ]; then
- names=(dispatch dispatch-systemd dispatch-s6 dispatch-electron code-search)
-else
- names=("$@")
-fi
-
-for name in "${names[@]}"; do
- path=$(resolve_pkg "$name")
- if [ -z "$path" ]; then
- # --all is lenient: skip missing packages
- if [ "${1:-}" = "--all" ]; then
- echo "warn: no built package found for '$name', skipping" >&2
- continue
- fi
- echo "error: no built package found for '$name'" >&2
- echo " run bin/build-pkg (or bin/build-pkg-electron) first." >&2
- exit 1
- fi
- paths+=("$path")
-done
-
-if [ ${#paths[@]} -eq 0 ]; then
- echo "error: nothing to install." >&2
- exit 1
-fi
-
-echo "Installing:"
-printf ' %s\n' "${paths[@]}"
-echo ""
-yay -U "${paths[@]}"
diff --git a/bin/prod_secrets b/bin/prod_secrets
deleted file mode 100755
index 17e35c2..0000000
--- a/bin/prod_secrets
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-# Force GPG to use terminal-based pinentry (required for SSH sessions)
-export GPG_TTY=$(tty)
-
-echo "Checking production secrets for Dispatch..." >&2
-echo "" >&2
-
-# --- OpenCode Go API Key (shared across environments) ---
-
-if gopass show -o projects/ai-api/opencode_go_key &>/dev/null; then
- echo "[ok] OpenCode Go API key exists" >&2
-else
- echo "OpenCode Go API key not found in gopass." >&2
- echo "" >&2
- echo " 1. Go to https://opencode.ai/auth" >&2
- echo " 2. Sign in and copy your API key" >&2
- echo " 3. Paste it below" >&2
- echo "" >&2
- read -rp "Enter your OpenCode Go API key: " OPENCODE_KEY
- echo "$OPENCODE_KEY" | gopass insert -f projects/ai-api/opencode_go_key
- echo "[ok] OpenCode Go API key stored" >&2
-fi
-
-echo "" >&2
-echo "All production secrets are configured. Outputting .env:" >&2
-echo "" >&2
-
-# --- Output .env format to stdout ---
-
-echo "OPENCODE_API_KEY=$(gopass show -o projects/ai-api/opencode_go_key)"
-echo "DISPATCH_MODEL=deepseek-v4-flash"
diff --git a/bin/seed-opencode-keys.ts b/bin/seed-opencode-keys.ts
deleted file mode 100644
index c481b8d..0000000
--- a/bin/seed-opencode-keys.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env bun
-/**
- * Seed API keys from environment variables into the SQLite database.
- */
-import { getDatabasePath, setApiKey } from "../packages/core/src/index.js";
-
-console.log(`Database: ${getDatabasePath()}\n`);
-
-const keys = [
- { keyId: "opencode-1", provider: "opencode-go", envVar: "OPENCODE_KEY_1" },
- { keyId: "opencode-2", provider: "opencode-go", envVar: "OPENCODE_KEY_2" },
- { keyId: "copilot", provider: "github-copilot", envVar: "COPILOT_TOKEN" },
- { keyId: "opencode-cookie", provider: "opencode-go", envVar: "OPENCODE_COOKIE" },
- { keyId: "opencode-ws1", provider: "opencode-go", envVar: "OPENCODE_WS1_ID" },
- { keyId: "opencode-ws2", provider: "opencode-go", envVar: "OPENCODE_WS2_ID" },
-];
-
-for (const { keyId, provider, envVar } of keys) {
- const value = process.env[envVar];
- if (value) {
- setApiKey(keyId, provider, value);
- console.log(`${keyId}: imported from $${envVar}`);
- } else {
- console.log(`${keyId}: SKIPPED ($${envVar} not set)`);
- }
-}
-
-console.log("\nDone.");
diff --git a/bin/service b/bin/service
deleted file mode 100755
index 62471b9..0000000
--- a/bin/service
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Dispatch runs as system service instances keyed on the *invoking* user, so
-# `bin/service start` brings the services up running as you (e.g. dispatch-api@tradam).
-RUN_USER="$(id -un)"
-API_UNIT="dispatch-api@${RUN_USER}"
-FRONTEND_UNIT="dispatch-frontend@${RUN_USER}"
-
-cmd="${1:-help}"
-shift 2>/dev/null || true
-
-usage() {
- cat <<EOF
-Usage: bin/service <command>
-
-Commands:
- install Install the dispatch packages (systemd system unit templates +
- application files in /opt/dispatch).
- start Start dispatch-api and dispatch-frontend as ${RUN_USER}.
- If already running, restart instead.
- Prints the frontend URL when ready.
- stop Stop dispatch-api and dispatch-frontend.
- status Show status of both services.
- logs Tail journal output for both services.
-
-Services run as system instances for the current user:
- ${API_UNIT}
- ${FRONTEND_UNIT}
-Start/stop use sudo (system manager). After install, configure
-/etc/dispatch/dispatch-api.conf before starting.
-EOF
-}
-
-install() {
- echo "==> Building fresh package..."
- "$PROJECT_DIR/bin/build-pkg"
-
- echo ""
- echo "==> Installing..."
- "$PROJECT_DIR/bin/install-pkg"
-
- sudo systemctl daemon-reload
- echo ""
- echo "==> Installed. Edit /etc/dispatch/dispatch-api.conf, then run:"
- echo " bin/service start"
-}
-
-have_units() {
- systemctl cat [email protected] &>/dev/null
-}
-
-start() {
- if ! have_units; then
- echo "dispatch services not installed. Run: bin/service install"
- return 1
- fi
- local api_active frontend_active
- api_active=$(systemctl is-active "$API_UNIT" 2>/dev/null || echo "inactive")
- frontend_active=$(systemctl is-active "$FRONTEND_UNIT" 2>/dev/null || echo "inactive")
-
- if [ "$api_active" = "active" ] || [ "$frontend_active" = "active" ]; then
- echo "==> Services already running (api=$api_active frontend=$frontend_active) — restarting"
- sudo systemctl restart "$API_UNIT" "$FRONTEND_UNIT"
- echo "dispatch-api + dispatch-frontend restarted (as ${RUN_USER})"
- else
- sudo systemctl start "$API_UNIT" "$FRONTEND_UNIT"
- echo "dispatch-api + dispatch-frontend started (as ${RUN_USER})"
- fi
- echo " → http://localhost:18391"
-}
-
-stop() {
- if ! have_units; then
- echo "dispatch services not installed."
- return 1
- fi
- sudo systemctl stop "$API_UNIT" "$FRONTEND_UNIT"
- echo "dispatch-api + dispatch-frontend stopped"
-}
-
-status() {
- if ! have_units; then
- echo "dispatch services not installed."
- return 1
- fi
- systemctl status "$API_UNIT" "$FRONTEND_UNIT" --no-pager 2>/dev/null || true
-}
-
-logs() {
- sudo journalctl -u "$API_UNIT" -u "$FRONTEND_UNIT" -f "$@"
-}
-
-case "$cmd" in
- install) install ;;
- start) start ;;
- stop) stop ;;
- status) status ;;
- logs) logs "$@" ;;
- help|--help|-h) usage ;;
- *) echo "Unknown command: $cmd"; echo; usage; exit 1 ;;
-esac
diff --git a/bin/test b/bin/test
deleted file mode 100755
index 61b31ce..0000000
--- a/bin/test
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Run the test suite inside the API container
-# Uses the api service since it has access to the full workspace
-sudo docker compose -f "$PROJECT_DIR/docker-compose.yml" \
- run --rm api bun run test "$@"
diff --git a/bin/up b/bin/up
deleted file mode 100755
index a47135c..0000000
--- a/bin/up
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Pass host user identity so the container runs as the same UID/GID
-export HOST_UID="$(id -u)"
-export HOST_GID="$(id -g)"
-export HOST_USER="$(whoami)"
-
-# --- DEBUG=1 convenience flag ------------------------------------
-# `DEBUG=1 bin/up` turns on full LLM debug logging (request/response
-# bodies) AND the per-step usage split (cache read/write tokens), and
-# routes the JSON log files into `logging/` at the project root. That
-# directory is mounted into the container at /app/logging via the
-# `.:/app` bind, so the files land on the host where you can
-# `tail -F logging/*.json` without `docker exec`. `logging/` is
-# gitignored.
-#
-# It only sets DEFAULTS -- any DISPATCH_DEBUG_* var you set explicitly
-# still wins, so fine-grained control (e.g. a custom verbosity or a
-# different log dir) is preserved.
-if [ -n "${DEBUG:-}" ] && [ "$DEBUG" != "0" ]; then
- : "${DISPATCH_DEBUG_LLM:=1}"
- : "${DISPATCH_DEBUG_USAGE:=1}"
- : "${DISPATCH_DEBUG_LLM_DIR:=/app/logging}"
-fi
-
-# Debug-logger pass-through. docker-compose only forwards env vars that are
-# (a) set in the parent shell AND (b) referenced in docker-compose.yml's
-# `environment:` block -- so without this `export` step the variables would
-# be invisible to the container even when the user prefixes the command with
-# DISPATCH_DEBUG_LLM=1. We re-export here (rather than relying on the shell's
-# inline `VAR=... cmd` syntax) so it works whether the user sets them inline,
-# in their shell rc, or via `.env`.
-#
-# All variables default to empty -- when unset, the logger short-circuits and
-# does nothing.
-export DISPATCH_DEBUG_LLM="${DISPATCH_DEBUG_LLM:-}"
-export DISPATCH_DEBUG_LLM_VERBOSITY="${DISPATCH_DEBUG_LLM_VERBOSITY:-}"
-export DISPATCH_DEBUG_USAGE="${DISPATCH_DEBUG_USAGE:-}"
-# Container-side log directory. Empty => the logger uses its built-in default
-# (/tmp/dispatch/llm-debug). DEBUG=1 sets it to /app/logging (see above).
-export DISPATCH_DEBUG_LLM_DIR="${DISPATCH_DEBUG_LLM_DIR:-}"
-
-# Pre-create the debug log directory owned by the host user. Without this,
-# docker auto-creates the bind-mount source as root on first start, and the
-# container's bun process (running as host UID) then gets EACCES on every log
-# write -- silent except for `[dispatch-debug] Failed to write ...: EACCES`
-# lines drowned in stderr.
-#
-# The host path depends on which container dir the logger targets:
-# - /app/<sub> -> the project bind-mount, host path $PROJECT_DIR/<sub>
-# (already host-owned; a plain mkdir is enough).
-# - otherwise -> the dedicated /tmp/dispatch/llm-debug volume; may have
-# been root-created by a prior run, so fix ownership.
-case "${DISPATCH_DEBUG_LLM_DIR}" in
- /app/*)
- HOST_LOG_DIR="$PROJECT_DIR/${DISPATCH_DEBUG_LLM_DIR#/app/}"
- mkdir -p "$HOST_LOG_DIR" 2>/dev/null || true
- ;;
- *)
- HOST_LOG_DIR=/tmp/dispatch/llm-debug
- mkdir -p "$HOST_LOG_DIR" 2>/dev/null || true
- if [ ! -O "$HOST_LOG_DIR" ]; then
- current_owner=$(stat -c '%U' "$HOST_LOG_DIR" 2>/dev/null || echo "unknown")
- echo "bin/up: $HOST_LOG_DIR is owned by '$current_owner', fixing ownership to '$HOST_USER'..."
- sudo chown -R "$HOST_UID:$HOST_GID" "$HOST_LOG_DIR"
- fi
- ;;
-esac
-
-if [ -n "${DISPATCH_DEBUG_LLM}" ]; then
- echo "bin/up: debug logging ON -> ${DISPATCH_DEBUG_LLM_DIR:-/tmp/dispatch/llm-debug} (host: $HOST_LOG_DIR)"
-fi
-
-# Start all services
-docker compose -f "$PROJECT_DIR/docker-compose.yml" up "$@"
diff --git a/bin/up-backend b/bin/up-backend
deleted file mode 100755
index 894fc01..0000000
--- a/bin/up-backend
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-# Force GPG to use terminal-based pinentry (required for SSH sessions)
-export GPG_TTY=$(tty)
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Load secrets from gopass
-OPENCODE_API_KEY="$(gopass show -o projects/ai-api/opencode_go_key)"
-
-# Pass host user identity so the container runs as the same UID/GID
-export HOST_UID="$(id -u)"
-export HOST_GID="$(id -g)"
-export HOST_USER="$(whoami)"
-
-# Start API service only
-sudo -E OPENCODE_API_KEY="$OPENCODE_API_KEY" \
- HOST_UID="$HOST_UID" HOST_GID="$HOST_GID" HOST_USER="$HOST_USER" \
- docker compose -f "$PROJECT_DIR/docker-compose.yml" up api "$@"
diff --git a/bin/up-frontend b/bin/up-frontend
deleted file mode 100755
index 82b4523..0000000
--- a/bin/up-frontend
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Frontend has no secrets — start frontend service only
-sudo docker compose -f "$PROJECT_DIR/docker-compose.yml" up frontend "$@"