194 lines
6.1 KiB
Bash
Executable file
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
|