#!/usr/bin/env bash # Verify that citation-evidence is installed consistently with its ecosystem # layout. citation-evidence is the umbrella repo; @citation-evidence/engine # must resolve from a sibling citation-engine checkout (see CE-WP-0009). set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" ENGINE_SIBLING="$ROOT/../citation-engine" ENGINE_DEP="link:../citation-engine" ENGINE_PKG="@citation-evidence/engine" errors=0 warnings=0 ok() { printf ' \033[32m✓\033[0m %s\n' "$1"; } fail() { printf ' \033[31m✗\033[0m %s\n' "$1"; errors=$((errors + 1)); } warn() { printf ' \033[33m!\033[0m %s\n' "$1"; warnings=$((warnings + 1)); } hint() { printf ' → %s\n' "$1"; } section() { printf '\n%s\n' "$1" } fix_clone_engine() { hint "Clone citation-engine as a sibling of this repo:" hint " cd $(dirname "$ROOT")" hint " git clone citation-engine" hint "Expected layout:" hint " $(dirname "$ROOT")/citation-evidence/ (this repo)" hint " $(dirname "$ROOT")/citation-engine/ (required sibling)" } printf 'citation-evidence install consistency check\n' printf 'Umbrella root: %s\n' "$ROOT" section "Required sibling: citation-engine" if [[ -d "$ENGINE_SIBLING" ]]; then ok "citation-engine directory exists at ../citation-engine" else fail "citation-engine not found at ../citation-engine" fix_clone_engine fi if [[ -f "$ENGINE_SIBLING/package.json" ]]; then ok "citation-engine/package.json present" engine_name="$(node -e " const p = require('$ENGINE_SIBLING/package.json'); process.stdout.write(p.name ?? ''); " 2>/dev/null || true)" if [[ "$engine_name" == "$ENGINE_PKG" ]]; then ok "citation-engine package name is $ENGINE_PKG" else fail "citation-engine package name is '${engine_name:-}' (expected $ENGINE_PKG)" hint "Check that ../citation-engine is the correct repository." fi elif [[ -d "$ENGINE_SIBLING" ]]; then fail "citation-engine/package.json missing" hint "../citation-engine does not look like a valid checkout." fi for path in src/shared/index.ts src/engine/index.ts; do if [[ -f "$ENGINE_SIBLING/$path" ]]; then ok "citation-engine/$path present" elif [[ -d "$ENGINE_SIBLING" ]]; then fail "citation-engine/$path missing" hint "Run 'git pull' in ../citation-engine or check out a complete tree." fi done section "package.json link dependency" declared="$(node -e " const p = require('$ROOT/package.json'); const v = p.dependencies?.['$ENGINE_PKG']; process.stdout.write(v ?? ''); " 2>/dev/null || true)" if [[ "$declared" == "$ENGINE_DEP" ]]; then ok "package.json declares \"$ENGINE_PKG\": \"$ENGINE_DEP\"" else fail "package.json should declare \"$ENGINE_PKG\": \"$ENGINE_DEP\" (found: ${declared:-})" fi section "node_modules resolution" linked="$ROOT/node_modules/@citation-evidence/engine" if [[ -e "$linked" ]]; then ok "node_modules/@citation-evidence/engine exists" real="$(cd "$linked" && pwd -P 2>/dev/null || true)" expected="$(cd "$ENGINE_SIBLING" 2>/dev/null && pwd -P || true)" if [[ -n "$real" && -n "$expected" && "$real" == "$expected" ]]; then ok "link resolves to ../citation-engine" elif [[ -n "$real" && -n "$expected" ]]; then fail "node_modules link points to $real (expected $expected)" hint "Run 'pnpm install' from citation-evidence after fixing the sibling checkout." fi else fail "node_modules/@citation-evidence/engine not found" hint "Run 'pnpm install' from the citation-evidence root." if [[ ! -d "$ENGINE_SIBLING" ]]; then fix_clone_engine fi fi section "Toolchain" if command -v node >/dev/null 2>&1; then node_ver="$(node -v | sed 's/^v//')" ok "node $node_ver available" if [[ -f "$ROOT/.nvmrc" ]]; then want="$(tr -d '[:space:]' < "$ROOT/.nvmrc")" node_major_minor="$(printf '%s' "$node_ver" | cut -d. -f1-2)" want_major_minor="$(printf '%s' "$want" | cut -d. -f1-2)" if [[ "$node_major_minor" == "$want_major_minor" ]]; then ok "node version matches .nvmrc ($want)" else warn "node $node_ver does not match .nvmrc ($want) — use nvm/fnm to switch" hint " nvm use # or: fnm use" fi fi else fail "node not found on PATH" hint "Install Node 20 LTS (see .nvmrc)." fi if command -v pnpm >/dev/null 2>&1; then ok "pnpm $(pnpm -v) available" else fail "pnpm not found on PATH" hint "Enable corepack: corepack enable && corepack prepare pnpm@9.15.0 --activate" fi section "Optional sister repos (INTENT-only during MVP)" parent="$(dirname "$ROOT")" for repo in evidence-anchor evidence-source evidence-binder citation-work; do if [[ -f "$parent/$repo/INTENT.md" ]]; then ok "$repo checked out (optional)" else warn "$repo not present at ../$repo (optional — not required to run the umbrella)" fi done section "Stale in-repo engine copies" if [[ -d "$ROOT/src/shared" || -d "$ROOT/src/engine" ]]; then fail "src/shared/ or src/engine/ still present in citation-evidence (removed in CE-WP-0009)" hint "Delete local copies; engine code must come from ../citation-engine only." else ok "no duplicate src/shared or src/engine in umbrella" fi printf '\n' if [[ "$errors" -gt 0 ]]; then printf '\033[31mInstall check failed (%d error(s), %d warning(s)).\033[0m\n' "$errors" "$warnings" printf 'Fix the items above, then run: pnpm install && make check-install\n' exit 1 fi if [[ "$warnings" -gt 0 ]]; then printf '\033[33mInstall check passed with %d warning(s).\033[0m\n' "$warnings" else printf '\033[32mInstall check passed.\033[0m\n' fi exit 0