#!/bin/bash # Report, from the host, how far the Cowork probe has actually got. # # The probe asks four questions that only the operator can answer in a Cowork # session. But three of them leave traces on this Mac, and a trace is a # measurement where "what did you see in the UI" is a recollection. This script # reads those traces so each step can be verified before the next one starts. # # It reports; it does not gate. Exit 0 when every check has landed, 1 while any # is still pending, 2 on a broken precondition. # # bash 3.2-clean, ASCII-only, read-only: it opens nothing and writes nothing. set -u SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) REPO_ROOT=$(cd "$SCRIPT_DIR/.." && pwd) PROBE_DOC="$REPO_ROOT/docs/cowork-probe.md" FIXTURE="$REPO_ROOT/tests/fixtures/cowork-probe" ARCHIVE="${JOBBSOK_PROBE_ARCHIVE:-/tmp/jobbsok-probe.plugin}" CLAUDE_LOGS="$HOME/Library/Logs/Claude" MCP_LOG="$CLAUDE_LOGS/mcp-server-probe-tools.log" CLAUDE_SUPPORT="$HOME/Library/Application Support/Claude" pending=0 say() { printf '%s\n' "$1"; } done_() { printf ' [DONE] %s\n' "$1"; } pend() { printf ' [PENDING] %s\n' "$1"; pending=$((pending+1)); } info() { printf ' %s\n' "$1"; } say "" say "=== 1. Probe vehicle and archive ============================================" n=$(find "$FIXTURE" -type f 2>/dev/null | wc -l | tr -d ' ') if [ "$n" = "4" ]; then done_ "probe vehicle: 4 files under tests/fixtures/cowork-probe" else pend "probe vehicle: expected 4 files, found $n" fi if [ -f "$ARCHIVE" ]; then a=$(unzip -Z1 "$ARCHIVE" 2>/dev/null | wc -l | tr -d ' ') leak=$(unzip -Z1 "$ARCHIVE" 2>/dev/null | grep -cE '^\.git|STATE\.md|\.venv|^\.claude/') if [ "$a" = "4" ] && [ "$leak" = "0" ]; then done_ "archive: $ARCHIVE ($a files, no leaked entries)" else pend "archive: $ARCHIVE has $a entries and $leak leaked ones - rebuild it" fi else pend "archive not built yet: $ARCHIVE" info "cd tests/fixtures/cowork-probe && zip -X $ARCHIVE .claude-plugin/plugin.json .mcp.json probe_tools.py skills/probe-versjon/SKILL.md" fi say "" say "=== 2. Is jobbsok-probe installed in Cowork? =================================" # Bounded on purpose. A recursive content grep over the whole Claude support # directory walks caches and VM images and does not finish; the plugin store is # a known, shallow place, so look there by name and read only the small # manifests. A check that hangs is not a check. SESSIONS="$CLAUDE_SUPPORT/local-agent-mode-sessions" hits=$(find "$SESSIONS" -maxdepth 6 -name '*jobbsok-probe*' 2>/dev/null | head -5) for m in $(find "$SESSIONS" -maxdepth 4 \( -name 'manifest.json' -o -name 'cowork_settings.json' -o -name 'known_marketplaces.json' \) 2>/dev/null); do if grep -q 'jobbsok-probe' "$m" 2>/dev/null; then hits="$hits $m" fi done hits=$(printf '%s\n' "$hits" | grep -v '^$') if [ -n "$hits" ]; then done_ "Cowork store mentions jobbsok-probe:" printf '%s\n' "$hits" | sed 's|^| |' else pend "no trace of jobbsok-probe in Cowork's store yet" info "Upload the archive, or drag it into the Cowork chat and accept it." fi say "" say "=== 3. Did Cowork spawn the probe-tools server on THIS Mac? ==================" say " (this is the -Host-MCP: question, measured rather than recalled)" if [ -f "$MCP_LOG" ]; then done_ "log exists: $MCP_LOG" info "last written: $(stat -f '%Sm' "$MCP_LOG" 2>/dev/null)" for m in initialize tools/list tools/call; do if grep -q "method=\"$m\"" "$MCP_LOG" 2>/dev/null; then done_ "handshake: $m seen" else pend "handshake: $m NOT seen in the log" fi done started=$(grep -h '\[probe-tools\] started on' "$MCP_LOG" 2>/dev/null | tail -1) if [ -n "$started" ]; then done_ "server's own stderr: $started" else pend "the server never printed its start line - it may have failed to launch" fi else pend "no log at $MCP_LOG" info "Claude names each server's log mcp-server-.log. No file means" info "Cowork never even attempted to start probe-tools." fi if pgrep -f probe_tools.py >/dev/null 2>&1; then done_ "process alive right now: $(pgrep -fl probe_tools.py | head -1 | cut -c1-100)" else info "no probe_tools.py process running at this instant (it may be started" info "on demand, so this alone is not a nei - the log above is the record)" fi say "" say "=== 4. Are the four answers written down? ===================================" RE='^- (Sesjonsmodus|Host-MCP|python3|CLAUDE_PLUGIN_ROOT): +(lokal VM|sky|ja|nei)\b' c=$(grep -cE "$RE" "$PROBE_DOC" 2>/dev/null) if [ "$c" = "4" ]; then done_ "all four answered - plan Step 1 Verify passes" grep -E '^- (Sesjonsmodus|Host-MCP|python3|CLAUDE_PLUGIN_ROOT):' "$PROBE_DOC" | sed 's|^| |' else pend "$c of 4 answered in docs/cowork-probe.md" grep -E '^- (Sesjonsmodus|Host-MCP|python3|CLAUDE_PLUGIN_ROOT):' "$PROBE_DOC" 2>/dev/null | sed 's|^| |' fi say "" say "============================================================================" if [ "$pending" -eq 0 ]; then say "ALL CHECKS LANDED." exit 0 fi say "$pending check(s) still pending." exit 1