diff --git a/Makefile b/Makefile index 2c79ce7..66770c5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: preview dev build test typecheck lint +.PHONY: preview dev build test typecheck lint check-install # Build the production bundle then serve it locally with vite preview. # Prints the URL (default http://localhost:4173/) once the server is ready. @@ -21,3 +21,7 @@ typecheck: lint: pnpm lint + +# Verify sibling citation-engine checkout, link dependency, and toolchain. +check-install: + @bash scripts/check-install.sh diff --git a/README.md b/README.md index 5bc2eb9..44e6f11 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Requirements: Node 20 LTS (see `.nvmrc`) and `pnpm` 9. ```bash # citation-engine must be checked out next to this repo (../citation-engine) +make check-install # diagnose layout problems before install pnpm install pnpm dev # vite dev server (once src/app/ has a real entry) pnpm test # vitest one-shot diff --git a/scripts/check-install.sh b/scripts/check-install.sh new file mode 100755 index 0000000..7ce22bb --- /dev/null +++ b/scripts/check-install.sh @@ -0,0 +1,162 @@ +#!/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 \ No newline at end of file