mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 23:14:37 +00:00
feat(scripts): pnpm work + pnpm debug for agent-driven workflows (#1105)
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# scripts/debug
|
||||
|
||||
Agent-friendly wrappers around the project's test runners. Each command runs
|
||||
the underlying tool with full output **teed to a log file** under
|
||||
`target/debug-logs/`, while keeping stdout small (summary + failure blocks).
|
||||
|
||||
Use `--verbose` on any runner to also stream the raw output.
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
# Vitest
|
||||
pnpm debug unit # full suite
|
||||
pnpm debug unit src/components/Foo.test.tsx # one file (positional pattern)
|
||||
pnpm debug unit -t "renders empty state" # filter by test name
|
||||
pnpm debug unit Foo -t "renders empty" --verbose
|
||||
|
||||
# WDIO E2E (one spec at a time)
|
||||
pnpm debug e2e test/e2e/specs/smoke.spec.ts
|
||||
pnpm debug e2e test/e2e/specs/cron-jobs-flow.spec.ts cron-jobs --verbose
|
||||
|
||||
# cargo tests (uses scripts/test-rust-with-mock.sh)
|
||||
pnpm debug rust
|
||||
pnpm debug rust json_rpc_e2e
|
||||
|
||||
# Inspect saved logs
|
||||
pnpm debug logs # list 50 most recent
|
||||
pnpm debug logs last # print most recent (last 400 lines)
|
||||
pnpm debug logs unit # most recent matching prefix "unit"
|
||||
pnpm debug logs last --tail 100
|
||||
```
|
||||
|
||||
Logs land in `target/debug-logs/<kind>-<suffix>-<timestamp>.log`. The directory
|
||||
is created on demand and is safe to delete — nothing else writes there.
|
||||
|
||||
## Why
|
||||
|
||||
- **Filtering** — positional pattern + `-t "<name>"` for Vitest, single spec
|
||||
for WDIO; agents don't have to grep the whole tree on every change.
|
||||
- **Bounded output** — the default summary fits in agent context. Full output
|
||||
is one `pnpm debug logs last` away.
|
||||
- **Stable surface** — the runners' flags can churn; this wrapper keeps the
|
||||
contract small (positional + a couple of flags) so prompts don't break.
|
||||
|
||||
The wrappers don't replace the project test runners — they invoke the
|
||||
underlying tools/scripts with log capture.
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
# Dispatcher for `pnpm debug <cmd> <args…>`.
|
||||
# Agent-friendly wrappers around the project's test/run scripts.
|
||||
# Commands: unit | e2e | rust | logs
|
||||
|
||||
set -euo pipefail
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: pnpm debug <command> [args]
|
||||
|
||||
Commands:
|
||||
unit [pattern] [-t "<name>"] [--watch] [--verbose]
|
||||
Run Vitest. Full log goes to target/debug-logs/unit-<ts>.log;
|
||||
stdout shows only summary + failure blocks unless --verbose.
|
||||
e2e <spec> [log-suffix] [--verbose]
|
||||
Run a single WDIO spec via app/scripts/e2e-run-spec.sh.
|
||||
Full log goes to target/debug-logs/e2e-<suffix>-<ts>.log.
|
||||
rust [test-filter] [--verbose]
|
||||
Run cargo tests with the mock backend (test-rust-with-mock.sh).
|
||||
Full log goes to target/debug-logs/rust-<ts>.log.
|
||||
logs [list|<run-id>|last] [--head N | --tail N]
|
||||
Inspect saved debug-log files. `last` shows the most recent.
|
||||
|
||||
Flags common to runners:
|
||||
--verbose Stream full output to stdout in addition to the log file.
|
||||
|
||||
Exit code = the underlying tool's exit code.
|
||||
EOF
|
||||
}
|
||||
|
||||
cmd="${1:-}"
|
||||
if [ -z "$cmd" ] || [ "$cmd" = "-h" ] || [ "$cmd" = "--help" ]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
shift
|
||||
|
||||
case "$cmd" in
|
||||
unit|e2e|rust|logs)
|
||||
exec "$here/${cmd}.sh" "$@"
|
||||
;;
|
||||
*)
|
||||
echo "[debug] unknown command: $cmd" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
# e2e.sh <spec> [log-suffix] [--verbose]
|
||||
# Wraps app/scripts/e2e-run-spec.sh with log capture + summary.
|
||||
|
||||
set -euo pipefail
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=lib.sh
|
||||
source "$here/lib.sh"
|
||||
|
||||
verbose=0
|
||||
spec=""
|
||||
suffix=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--verbose) verbose=1; shift ;;
|
||||
-*)
|
||||
echo "[debug:e2e] unknown flag: $1" >&2; exit 1 ;;
|
||||
*)
|
||||
if [ -z "$spec" ]; then spec="$1"
|
||||
elif [ -z "$suffix" ]; then suffix="$1"
|
||||
else echo "[debug:e2e] unexpected arg: $1" >&2; exit 1
|
||||
fi
|
||||
shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$spec" ]; then
|
||||
echo "Usage: pnpm debug e2e <spec-path> [log-suffix] [--verbose]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
repo_root="$(debug_repo_root)"
|
||||
log_dir="$(debug_log_dir)"
|
||||
[ -n "$suffix" ] || suffix="$(basename "$spec" .spec.ts)"
|
||||
safe_suffix="$(basename -- "$suffix")"
|
||||
safe_suffix="${safe_suffix//[^[:alnum:]._-]/-}"
|
||||
[ -n "$safe_suffix" ] || safe_suffix="spec"
|
||||
log="$log_dir/e2e-${safe_suffix}-$(debug_timestamp).log"
|
||||
|
||||
echo "[debug:e2e] spec: $spec"
|
||||
echo "[debug:e2e] log: $log"
|
||||
rc=0
|
||||
debug_run "$log" "$verbose" -- bash "$repo_root/app/scripts/e2e-run-spec.sh" "$spec" "$suffix" || rc=$?
|
||||
|
||||
if [ "$verbose" != "1" ]; then
|
||||
debug_summarize_wdio "$log"
|
||||
fi
|
||||
|
||||
if [ "$rc" != "0" ]; then
|
||||
echo
|
||||
echo "[debug:e2e] FAILED (exit $rc) — full log: $log"
|
||||
else
|
||||
echo "[debug:e2e] OK — log: $log"
|
||||
fi
|
||||
exit "$rc"
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared helpers for scripts/debug/*.sh. Source; do not execute.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
debug_repo_root() {
|
||||
(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
|
||||
}
|
||||
|
||||
debug_log_dir() {
|
||||
local root
|
||||
root="$(debug_repo_root)"
|
||||
mkdir -p "$root/target/debug-logs"
|
||||
echo "$root/target/debug-logs"
|
||||
}
|
||||
|
||||
debug_timestamp() {
|
||||
date +%Y%m%d-%H%M%S
|
||||
}
|
||||
|
||||
# Run a command, tee its combined output to a log file, return its exit code.
|
||||
# Usage: debug_run <log_file> <verbose:0|1> -- <cmd> [args…]
|
||||
debug_run() {
|
||||
local log="$1"; shift
|
||||
local verbose="$1"; shift
|
||||
if [ "${1:-}" = "--" ]; then shift; fi
|
||||
|
||||
local rc=0
|
||||
if [ "$verbose" = "1" ]; then
|
||||
set +e
|
||||
"$@" 2>&1 | tee "$log"
|
||||
rc=${PIPESTATUS[0]}
|
||||
set -e
|
||||
else
|
||||
set +e
|
||||
"$@" >"$log" 2>&1
|
||||
rc=$?
|
||||
set -e
|
||||
fi
|
||||
return "$rc"
|
||||
}
|
||||
|
||||
# Print a short summary + the failure block(s) from a Vitest log.
|
||||
debug_summarize_vitest() {
|
||||
local log="$1"
|
||||
echo
|
||||
echo "--- summary ---"
|
||||
grep -E '^[[:space:]]*(Test Files|Tests|Duration|Start at)' "$log" | tail -n 20 || true
|
||||
if grep -qE '^[[:space:]]*FAIL ' "$log"; then
|
||||
echo
|
||||
echo "--- failures ---"
|
||||
grep -E '^[[:space:]]*FAIL ' "$log" || true
|
||||
echo
|
||||
echo "--- failure detail (first 200 lines after first FAIL) ---"
|
||||
awk '/^[[:space:]]*FAIL /{found=1} found{print; n++; if (n>=200) exit}' "$log"
|
||||
fi
|
||||
}
|
||||
|
||||
# Print summary lines from a WDIO/Mocha run log.
|
||||
debug_summarize_wdio() {
|
||||
local log="$1"
|
||||
echo
|
||||
echo "--- summary ---"
|
||||
grep -E '(passing|failing|pending|tests?, )' "$log" | tail -n 10 || true
|
||||
if grep -qE '^[[:space:]]*[0-9]+\)' "$log"; then
|
||||
echo
|
||||
echo "--- failure detail ---"
|
||||
awk '/^[[:space:]]*[0-9]+\)/{found=1} found{print}' "$log" | head -n 200
|
||||
fi
|
||||
}
|
||||
|
||||
# Print summary + failure tails from a cargo-test log.
|
||||
debug_summarize_cargo() {
|
||||
local log="$1"
|
||||
echo
|
||||
echo "--- summary ---"
|
||||
grep -E '^test result:' "$log" | tail -n 20 || true
|
||||
if grep -qE '^failures:' "$log"; then
|
||||
echo
|
||||
echo "--- failures ---"
|
||||
awk '/^failures:/{found=1} found{print}' "$log" | head -n 200
|
||||
fi
|
||||
}
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
# logs.sh [list|last|<file>] [--head N | --tail N]
|
||||
|
||||
set -euo pipefail
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=lib.sh
|
||||
source "$here/lib.sh"
|
||||
|
||||
target="${1:-list}"
|
||||
shift || true
|
||||
mode=""
|
||||
lines="200"
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--head) mode="head"; lines="${2:?--head requires N}"; shift 2 ;;
|
||||
--head=*) mode="head"; lines="${1#*=}"; shift ;;
|
||||
--tail) mode="tail"; lines="${2:?--tail requires N}"; shift 2 ;;
|
||||
--tail=*) mode="tail"; lines="${1#*=}"; shift ;;
|
||||
*) echo "[debug:logs] unknown arg: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
log_dir="$(debug_log_dir)"
|
||||
|
||||
if [ "$target" = "list" ]; then
|
||||
ls -1t "$log_dir" 2>/dev/null | head -n 50
|
||||
exit 0
|
||||
fi
|
||||
|
||||
resolve_log() {
|
||||
local t="$1"
|
||||
if [ "$t" = "last" ]; then
|
||||
ls -1t "$log_dir" 2>/dev/null | head -n 1 | awk -v d="$log_dir" '{print d "/" $0}'
|
||||
return
|
||||
fi
|
||||
if [ -f "$t" ]; then echo "$t"; return; fi
|
||||
if [ -f "$log_dir/$t" ]; then echo "$log_dir/$t"; return; fi
|
||||
# Prefix match
|
||||
local match
|
||||
match=$(ls -1t "$log_dir" 2>/dev/null | grep -F "$t" | head -n 1 || true)
|
||||
if [ -n "$match" ]; then echo "$log_dir/$match"; return; fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
file="$(resolve_log "$target")"
|
||||
if [ -z "$file" ] || [ ! -f "$file" ]; then
|
||||
echo "[debug:logs] no log matching: $target" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[debug:logs] $file"
|
||||
case "$mode" in
|
||||
head) head -n "$lines" "$file" ;;
|
||||
tail) tail -n "$lines" "$file" ;;
|
||||
"")
|
||||
if [ "$(wc -l <"$file")" -gt 400 ]; then
|
||||
echo "--- log is long; showing last 400 lines (use --head/--tail to override) ---"
|
||||
tail -n 400 "$file"
|
||||
else
|
||||
cat "$file"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# rust.sh [test-filter] [--verbose] [-- <cargo-test-args>…]
|
||||
# Wraps scripts/test-rust-with-mock.sh.
|
||||
|
||||
set -euo pipefail
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=lib.sh
|
||||
source "$here/lib.sh"
|
||||
|
||||
verbose=0
|
||||
filter=""
|
||||
passthrough=()
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--verbose) verbose=1; shift ;;
|
||||
--) shift; passthrough+=("$@"); break ;;
|
||||
-*) passthrough+=("$1"); shift ;;
|
||||
*)
|
||||
if [ -z "$filter" ]; then filter="$1"; else passthrough+=("$1"); fi
|
||||
shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
repo_root="$(debug_repo_root)"
|
||||
log_dir="$(debug_log_dir)"
|
||||
log="$log_dir/rust-$(debug_timestamp).log"
|
||||
|
||||
cmd=(bash "$repo_root/scripts/test-rust-with-mock.sh")
|
||||
if [ ${#passthrough[@]} -gt 0 ]; then
|
||||
cmd+=("${passthrough[@]}")
|
||||
fi
|
||||
if [ -n "$filter" ]; then
|
||||
cmd+=("$filter")
|
||||
fi
|
||||
|
||||
echo "[debug:rust] log: $log"
|
||||
echo "[debug:rust] cmd: ${cmd[*]}"
|
||||
rc=0
|
||||
debug_run "$log" "$verbose" -- "${cmd[@]}" || rc=$?
|
||||
|
||||
if [ "$verbose" != "1" ]; then
|
||||
debug_summarize_cargo "$log"
|
||||
fi
|
||||
|
||||
if [ "$rc" != "0" ]; then
|
||||
echo
|
||||
echo "[debug:rust] FAILED (exit $rc) — full log: $log"
|
||||
else
|
||||
echo "[debug:rust] OK — log: $log"
|
||||
fi
|
||||
exit "$rc"
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
# unit.sh [pattern] [-t "<name>"] [--watch] [--verbose] [-- <vitest-args>…]
|
||||
# Wraps `pnpm --filter openhuman-app test:unit`.
|
||||
|
||||
set -euo pipefail
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=lib.sh
|
||||
source "$here/lib.sh"
|
||||
|
||||
verbose=0
|
||||
watch=0
|
||||
pattern=""
|
||||
test_name=""
|
||||
passthrough=()
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--verbose) verbose=1; shift ;;
|
||||
--watch) watch=1; shift ;;
|
||||
-t) test_name="${2:?-t requires a value}"; shift 2 ;;
|
||||
-t=*) test_name="${1#*=}"; shift ;;
|
||||
--) shift; passthrough+=("$@"); break ;;
|
||||
-*)
|
||||
passthrough+=("$1"); shift ;;
|
||||
*)
|
||||
if [ -z "$pattern" ]; then pattern="$1"; else passthrough+=("$1"); fi
|
||||
shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
log_dir="$(debug_log_dir)"
|
||||
log="$log_dir/unit-$(debug_timestamp).log"
|
||||
|
||||
repo_root="$(debug_repo_root)"
|
||||
cd "$repo_root/app"
|
||||
|
||||
cmd=(pnpm exec vitest)
|
||||
if [ "$watch" = "1" ]; then
|
||||
: # vitest default is watch
|
||||
else
|
||||
cmd+=(run)
|
||||
fi
|
||||
cmd+=(--config test/vitest.config.ts)
|
||||
if [ -n "$test_name" ]; then
|
||||
cmd+=(-t "$test_name")
|
||||
fi
|
||||
if [ -n "$pattern" ]; then
|
||||
cmd+=("$pattern")
|
||||
fi
|
||||
if [ ${#passthrough[@]} -gt 0 ]; then
|
||||
cmd+=("${passthrough[@]}")
|
||||
fi
|
||||
|
||||
echo "[debug:unit] log: $log"
|
||||
echo "[debug:unit] cmd: ${cmd[*]}"
|
||||
rc=0
|
||||
debug_run "$log" "$verbose" -- "${cmd[@]}" || rc=$?
|
||||
|
||||
if [ "$verbose" != "1" ]; then
|
||||
debug_summarize_vitest "$log"
|
||||
fi
|
||||
|
||||
if [ "$rc" != "0" ]; then
|
||||
echo
|
||||
echo "[debug:unit] FAILED (exit $rc) — full log: $log"
|
||||
else
|
||||
echo "[debug:unit] OK — log: $log"
|
||||
fi
|
||||
exit "$rc"
|
||||
Reference in New Issue
Block a user