lilith-platform.live/codebase/@features/quinn-ai/engine/run
2026-05-18 03:50:11 -07:00

194 lines
6.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# coworker-agent ./run dispatcher.
# Usage: ./run quinn-outreach <subcommand> [args...]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${QUINN_OUTREACH_ENV_FILE:-/var/home/lilith/Code/@projects/@lilith/lilith-platform.live/infrastructure/.env.ports}"
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
. "$ENV_FILE"
set +a
fi
# Default outreach DB URL to the icloud DB URL (same DB per slice-1 design).
: "${QUINN_OUTREACH_DB_URL:=${QUINN_ICLOUD_DB_URL:-}}"
export QUINN_OUTREACH_DB_URL
usage() {
cat <<USAGE
usage: ./run <namespace> <subcommand> [args...]
namespaces:
quinn-outreach status [--last N] show heartbeat / event-log / awaiting-quinn
quinn-outreach calendar show show current calendar slots
quinn-outreach calendar set [--tonight-city=...] [--tomorrow-city=...] [--tour-end-default=...] [--tour-end-max=...] [--busy-dependent=true|false] [--location-state=...]
quinn-outreach watch run inbound watcher (LISTEN message_inserted)
quinn-outreach parse run reply-parser (Quinn's self-thread replies)
quinn-outreach loop run watcher + parser supervised (both children)
quinn-outreach smoke run end-to-end smoke test (10 steps)
quinn-outreach dry-run [--days=7] [--output=FILE] [--limit=200] [--unmasked] evaluate engine on real inbound (no send)
quinn-outreach autorespond run auto-respond engine (watches ALL inbound)
quinn-outreach scheduled-send list [--status=STATUS] show scheduled-send queue
quinn-outreach scheduled-send cancel <id> cancel a pending row
quinn-outreach scheduled-send-worker run durable send worker (heartbeat)
quinn-outreach booking-worker run §32 deposit-pending expiry worker
quinn-outreach mode get|set <auto-fire|draft-only|monitor-only|off> §39 engine-mode toggle
quinn-outreach block <handle> <reason> §49 add to hot-reload block-list
quinn-outreach unblock <handle> §49 remove from block-list
quinn-outreach list-blocked §49 show block-list
quinn-outreach init-block-list §49 seed block-list with §50 wrong-identity contacts
quinn-outreach test run unit tests via node --test
quinn-coworker worker run persona-driven nag loop (tick + LISTEN/NOTIFY)
USAGE
}
require_artifact() {
local f="$1"
if [[ ! -f "$f" ]]; then
echo "build artifact missing: $f" >&2
echo "run: (cd $SCRIPT_DIR && npm run build)" >&2
exit 3
fi
}
run_loop() {
local watcher="$SCRIPT_DIR/dist/agents/outreach/watcher.js"
local parser="$SCRIPT_DIR/dist/agents/outreach/reply-parser.js"
require_artifact "$watcher"
require_artifact "$parser"
local pids=()
cleanup() {
for pid in "${pids[@]:-}"; do
kill "$pid" 2>/dev/null || true
done
wait 2>/dev/null || true
}
trap cleanup INT TERM EXIT
node "$watcher" &
pids+=("$!")
node "$parser" &
pids+=("$!")
# Exit if any child dies — supervisor kills the survivor.
while true; do
for pid in "${pids[@]}"; do
if ! kill -0 "$pid" 2>/dev/null; then
echo "[loop] child $pid exited; tearing down" >&2
cleanup
exit 1
fi
done
sleep 2
done
}
if [[ $# -lt 2 ]]; then
usage
exit 2
fi
namespace="$1"
subcommand="$2"
shift 2
case "$namespace" in
quinn-outreach)
case "$subcommand" in
status)
DIST_FILE="$SCRIPT_DIR/dist/cli/status.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
calendar)
DIST_FILE="$SCRIPT_DIR/dist/cli/calendar.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
watch)
DIST_FILE="$SCRIPT_DIR/dist/agents/outreach/watcher.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
parse)
DIST_FILE="$SCRIPT_DIR/dist/agents/outreach/reply-parser.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
loop)
run_loop
;;
smoke)
DIST_FILE="$SCRIPT_DIR/dist/shared/smoke-test.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
dry-run)
DIST_FILE="$SCRIPT_DIR/dist/cli/dry-run.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
autorespond)
DIST_FILE="$SCRIPT_DIR/dist/agents/outreach/auto-respond-engine.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
test)
cd "$SCRIPT_DIR"
if [[ ! -d node_modules ]]; then
echo "node_modules missing — run: bun install" >&2
exit 3
fi
exec bun test src/__tests__/
;;
scheduled-send)
DIST_FILE="$SCRIPT_DIR/dist/cli/scheduled-send.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
scheduled-send-worker)
DIST_FILE="$SCRIPT_DIR/dist/workers/scheduled-send.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
booking-worker)
DIST_FILE="$SCRIPT_DIR/dist/agents/booking/booking-worker.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
mode|block|unblock|list-blocked|init-block-list)
DIST_FILE="$SCRIPT_DIR/dist/cli/mode-and-blocks.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$subcommand" "$@"
;;
*)
echo "unknown quinn-outreach subcommand: $subcommand" >&2
usage
exit 2
;;
esac
;;
quinn-coworker)
case "$subcommand" in
worker)
DIST_FILE="$SCRIPT_DIR/dist/agents/coworker/coworker-worker.js"
require_artifact "$DIST_FILE"
exec node "$DIST_FILE" "$@"
;;
*)
echo "unknown quinn-coworker subcommand: $subcommand" >&2
usage
exit 2
;;
esac
;;
*)
echo "unknown namespace: $namespace" >&2
usage
exit 2
;;
esac