Files
openhuman/scripts/worktree-bootstrap.sh
T
515c4f4b42 feat(imessage): testable tick harness + fix scanner never ingested (#746)
* fix(agent): orchestrator never sends users to external dashboards for connect

Agent was improvising guidance like 'open your Composio dashboard at
app.composio.dev' when users asked to connect a service, which is broken
UX for non-technical users. Add an explicit rule: route connect requests
to the in-app Settings → Connections path, never paste external URLs
or explain OAuth/Composio internals.

* plan: imessage live-tick harness

Plan doc for extracting run_single_tick from ScannerRegistry's
AppHandle-coupled loop, enabling unit tests with fake deps against
real chat.db and an ignored live-sidecar integration test.

Scaffolding only — code changes follow in subsequent commits.

Co-Authored-By: WOZCODE <contact@withwoz.com>

* feat(imessage): testable tick harness + fix scanner never ingested

Extract pure `run_single_tick` + `TickDeps` trait from `run_scanner`. Prod
path wraps in `HttpDeps`; tests use `FakeDeps` with real chat.db so the
scanner body runs without a Tauri AppHandle. Template for five more
Apple-native sources per the roadmap.

While running it end-to-end, two pre-existing bugs in the shipped scanner
surfaced — both had to be fixed for a tick to ever succeed:

1. `ScannerRegistry::ensure_scanner` called `tokio::spawn` from the Tauri
   `setup` hook, which runs before a Tokio reactor is active. Scanner
   task never spawned; main thread panicked with "no reactor running".
   Fix: `tauri::async_runtime::spawn`, which uses Tauri's own runtime.

2. `fetch_imessage_gate` used JSON pointer `/result/config/...` but the
   JSON-RPC `RpcOutcome` envelope nests one level deeper:
   `/result/result/config/...`. Gate always resolved to None, so every
   tick silently skipped even with iMessage connected. Fix: correct
   the pointer.

Verification: after both fixes, iMessage connected via
`openhuman.channels_connect` with `allowed_contacts=["*"]`, scanner
ingested 252 chat-day groups into `memory_docs` namespace
`imessage_default` — first successful ingest in the project's history.

Tests: 10 unit (9 existing + `skips_when_gate_disconnected`), 4 ignored
live-chat.db (2 existing + `run_single_tick_ingests_groups_from_real_chatdb`
+ `run_single_tick_keeps_cursor_on_group_failure`). All green.

Infra: `scripts/worktree-bootstrap.sh` — one-shot to init submodules,
symlink `.env`, build+stage sidecar, ensure tauri-cli. Worktrees didn't
inherit any of this, costing ~30 min of manual setup per branch.

Docs: `docs/superpowers/learnings/2026-04-21-imessage-harness-session.md`
captures what broke, why, and the debuggability ladder that would have
caught both bugs at merge time (launch-smoke CI, minimum).

Co-Authored-By: WOZCODE <contact@withwoz.com>

* chore(bootstrap): yarn install so husky hooks don't block push

Pre-push hook needs prettier; worktree had no node_modules. Friction
discovered pushing this branch.

Co-Authored-By: WOZCODE <contact@withwoz.com>

---------

Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
Co-authored-by: WOZCODE <contact@withwoz.com>
2026-04-21 22:25:44 -07:00

55 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Bootstrap a fresh git worktree for OpenHuman dev.
#
# `git worktree add` only checks out the tree. Submodules, untracked env
# files, and the staged core binary under app/src-tauri/binaries/ don't come
# along — the app won't build until they do. Run this once per worktree.
#
# Usage: from inside the worktree, `bash scripts/worktree-bootstrap.sh`.
set -euo pipefail
WORKTREE_ROOT="$(git rev-parse --show-toplevel)"
MAIN_ROOT="$(git worktree list --porcelain | awk '/^worktree / { print $2; exit }')"
if [[ "$WORKTREE_ROOT" == "$MAIN_ROOT" ]]; then
echo "[bootstrap] This IS the primary worktree — nothing to do." >&2
exit 0
fi
echo "[bootstrap] worktree: $WORKTREE_ROOT"
echo "[bootstrap] main: $MAIN_ROOT"
echo "[bootstrap] initializing submodules (tauri-cef, skills)..."
git -C "$WORKTREE_ROOT" submodule update --init --recursive
for rel in ".env" "app/.env.local"; do
src="$MAIN_ROOT/$rel"
dst="$WORKTREE_ROOT/$rel"
if [[ -f "$src" && ! -e "$dst" ]]; then
echo "[bootstrap] symlinking $rel from main"
mkdir -p "$(dirname "$dst")"
ln -s "$src" "$dst"
fi
done
# Stage the core sidecar binary. Either symlink to main's staged copy (fast,
# but will run main's code) OR build fresh from this worktree (slow, runs
# this branch's code). Default to fresh build — the whole point of a
# worktree is testing divergent code.
BIN="$WORKTREE_ROOT/app/src-tauri/binaries/openhuman-core-aarch64-apple-darwin"
if [[ ! -e "$BIN" ]]; then
echo "[bootstrap] building + staging core sidecar from this worktree..."
mkdir -p "$(dirname "$BIN")"
(cd "$WORKTREE_ROOT" && cargo build --bin openhuman-core)
(cd "$WORKTREE_ROOT/app" && yarn core:stage)
fi
echo "[bootstrap] installing node_modules (needed for husky hooks + prettier)..."
(cd "$WORKTREE_ROOT" && yarn install)
echo "[bootstrap] ensuring vendored tauri-cli installed..."
(cd "$WORKTREE_ROOT/app" && yarn tauri:ensure)
echo "[bootstrap] done. launch with: cd app && yarn dev:app"