From 3fce1c2e0e84608033566fdc59010ac50fec0fff Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sun, 5 Jul 2026 22:13:18 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20(scripts):=20Add=20validate-ai-?= =?UTF-8?q?workspace.sh=20to=20check=20onboarding=20scaffold?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/validate-ai-workspace.sh | 216 +++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100755 scripts/validate-ai-workspace.sh diff --git a/scripts/validate-ai-workspace.sh b/scripts/validate-ai-workspace.sh new file mode 100755 index 0000000..0c92971 --- /dev/null +++ b/scripts/validate-ai-workspace.sh @@ -0,0 +1,216 @@ +#!/usr/bin/env bash +# +# validate-ai-workspace.sh — check an installed AI onboarding workspace root +# (and, optionally, one or more org repo checkouts) against the layout +# defined in .claude/WORKSPACE.md (AAASM-3939) and installed by +# bootstrap-ai-workspace.sh (AAASM-3943). +# +# Usage: +# ./scripts/validate-ai-workspace.sh [repo-path...] +# +# Checks the workspace root for CLAUDE.md, AGENTS.md, .claude/rules/, and +# .claude/skills/, classifying each as: missing, a broken symlink, a local +# override (present but not a symlink back to a recognized .github clone), +# or correctly symlinked (OK). Local overrides are reported for visibility +# but do not fail validation — see the override model in .claude/WORKSPACE.md. +# +# Any extra repo-path arguments get a lightweight, informational check for +# their own `.claude/CLAUDE.md` and `AGENTS.md` (repo-level context gaps do +# not affect the exit code — this script validates the workspace scaffold, +# not repo-level completeness). +# +# Exit codes: +# 0 - every expected workspace item is present and either correctly +# symlinked or a recognized local override. Safe to use as a CI gate. +# 1 - at least one expected item is missing, or a symlink is broken. +# +# This is a plain local script: no network calls, only filesystem checks +# and local (non-network) `git remote -v` reads. + +set -euo pipefail + +usage() { + echo "Usage: $(basename "${BASH_SOURCE[0]}") [repo-path...]" >&2 +} + +if [[ $# -lt 1 ]]; then + echo "Error: is required." >&2 + usage + exit 1 +fi + +case "$1" in + -h|--help) + usage + exit 0 + ;; +esac + +WORKSPACE_ROOT="$1" +shift +declare -a REPO_PATHS=("$@") + +# --- Report buckets ---------------------------------------------------------- +# bash 3.2 (macOS default) throws "unbound variable" under `set -u` when +# expanding an array that has zero elements, so every expansion of these is +# guarded with an `${#arr[@]} -gt 0` length check before use. +declare -a MISSING=() +declare -a BROKEN=() +declare -a OVERRIDES=() +declare -a OK=() +declare -a REPO_NOTES=() + +# --- Helpers ------------------------------------------------------------- + +# is_dot_github_clone +# True if is inside a git checkout whose configured remotes reference +# the ai-agent-assembly/.github repo. `git remote -v` only reads local repo +# config; it makes no network calls. +is_dot_github_clone() { + local dir="$1" + local git_root + git_root="$(cd "${dir}" 2>/dev/null && git rev-parse --show-toplevel 2>/dev/null)" || return 1 + [[ -n "${git_root}" ]] || return 1 + git -C "${git_root}" remote -v 2>/dev/null | grep -qiE 'ai-agent-assembly/\.github(\.git)?' +} + +# check_item