// ci-generator/local-script.ts — Generate local planu-check.sh script (SPEC-201)
export const LOCAL_SCRIPT_PATH = 'planu-check.sh';
// -- Sections -----------------------------------------------------------------
function buildHeader(specsDir, failOnDrift, severityThreshold, detectDrift) {
    return [
        '#!/usr/bin/env bash',
        '# planu-check.sh — Local Planu spec validation (SPEC-201)',
        '# Runs the same checks as .github/workflows/planu-check.yml without GitHub-hosted runners.',
        '# Compatible with act (https://github.com/nektos/act) for local GitHub Actions execution.',
        '#',
        '# Usage:',
        '#   ./planu-check.sh               # validate specs (respects configured defaults)',
        '#   ./planu-check.sh --no-fail     # informational only, always exits 0',
        '#   ./planu-check.sh --severity=critical  # only fail on critical issues',
        '',
        'set -euo pipefail',
        '',
        '# -- Colors (disabled when not a TTY) --------------------------------------',
        'if [ -t 1 ]; then',
        '  RED="\\033[0;31m" YELLOW="\\033[1;33m" GREEN="\\033[0;32m" BLUE="\\033[0;34m"',
        '  BOLD="\\033[1m" RESET="\\033[0m"',
        'else',
        '  RED="" YELLOW="" GREEN="" BLUE="" BOLD="" RESET=""',
        'fi',
        '',
        '# -- Config ----------------------------------------------------------------',
        `SPECS_DIR="${specsDir}"`,
        `FAIL_ON_ISSUES=${failOnDrift ? 'true' : 'false'}`,
        `SEVERITY="${severityThreshold}"`,
        `DETECT_DRIFT=${detectDrift ? 'true' : 'false'}`,
        '',
        '# Parse flags',
        'for arg in "$@"; do',
        '  case "$arg" in',
        '    --no-fail) FAIL_ON_ISSUES=false ;;',
        '    --severity=*) SEVERITY="${arg#--severity=}" ;;',
        '  esac',
        'done',
    ];
}
function buildValidateSection() {
    return [
        '',
        '# -- Header ----------------------------------------------------------------',
        'echo -e "${BOLD}Planu Spec Check${RESET}"',
        'echo -e "Specs dir: ${BLUE}${SPECS_DIR}${RESET}"',
        'echo ""',
        '',
        'TOTAL=0',
        'ISSUES=0',
        '',
        'if [ ! -d "$SPECS_DIR" ]; then',
        '  echo -e "${RED}x Specs directory not found: $SPECS_DIR${RESET}"',
        '  exit 1',
        'fi',
        '',
        '# -- Validate specs --------------------------------------------------------',
        'for spec_dir in "$SPECS_DIR"/*/; do',
        '  [ -d "$spec_dir" ] || continue',
        '  SPEC_NAME=$(basename "$spec_dir")',
        '  TOTAL=$((TOTAL + 1))',
        '',
        '  SPEC_FILE="$spec_dir/spec.md"',
        '  if [ ! -f "$SPEC_FILE" ]; then',
        '    echo -e "  ${RED}x${RESET} $SPEC_NAME - missing spec.md"',
        '    ISSUES=$((ISSUES + 1))',
        '    continue',
        '  fi',
        '',
        '  CRITERIA=$(grep -c "^### AC-" "$SPEC_FILE" 2>/dev/null || echo "0")',
        '  SPEC_STATUS=$(grep -m1 "^status:" "$SPEC_FILE" 2>/dev/null | sed \'s/status:[[:space:]]*//\' | tr -d \'\\r\' || echo "")',
        '',
        '  if [ "$SPEC_STATUS" = "done" ] || [ "$SPEC_STATUS" = "discarded" ]; then',
        '    echo -e "  ${GREEN}ok${RESET} $SPEC_NAME - $SPEC_STATUS"',
        '  elif [ "$CRITERIA" = "0" ]; then',
        '    echo -e "  ${YELLOW}warn${RESET} $SPEC_NAME - no acceptance criteria"',
        '  else',
        '    echo -e "  ${BLUE}->${RESET} $SPEC_NAME - $SPEC_STATUS ($CRITERIA AC)"',
        '    ISSUES=$((ISSUES + 1))',
        '  fi',
        'done',
    ];
}
function buildDriftSection() {
    return [
        '',
        '# -- Basic drift detection ------------------------------------------------',
        'if [ "$DETECT_DRIFT" = "true" ] && command -v git &>/dev/null && git rev-parse --git-dir &>/dev/null; then',
        '  echo ""',
        '  echo -e "${BOLD}Drift Detection${RESET}"',
        '  CHANGED_FILES=$(git diff HEAD --name-only 2>/dev/null || echo "")',
        '  for spec_dir in "$SPECS_DIR"/*/; do',
        '    [ -f "$spec_dir/spec.md" ] || continue',
        '    SPEC_FILES=$(grep -oE \'src/[a-zA-Z0-9_./-]+\' "$spec_dir/spec.md" 2>/dev/null || echo "")',
        '    for sf in $SPEC_FILES; do',
        '      if echo "$CHANGED_FILES" | grep -q "$sf"; then',
        '        SPEC_NAME=$(basename "$spec_dir")',
        '        echo -e "  ${YELLOW}warn${RESET} Drift: $sf modified, belongs to $SPEC_NAME"',
        '      fi',
        '    done',
        '  done',
        'fi',
    ];
}
function buildCleanupCheckSection() {
    return [
        '',
        '# -- Git cleanup check (SPEC-203) — WARNING only, never fails CI -------------------',
        'if command -v git &>/dev/null && git rev-parse --git-dir &>/dev/null; then',
        '  echo ""',
        '  echo -e "${BOLD}Git Health Check${RESET}"',
        '',
        '  # Orphan worktrees: entries in .claude/worktrees/ whose branch is merged',
        '  WORKTREES_DIR=".claude/worktrees"',
        '  if [ -d "$WORKTREES_DIR" ]; then',
        '    MERGED_BRANCHES=$(git branch --merged develop 2>/dev/null || git branch --merged main 2>/dev/null || echo "")',
        '    while IFS= read -r -d "" wt_dir; do',
        '      wt_branch=$(git -C "$wt_dir" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")',
        '      if [ -n "$wt_branch" ] && echo "$MERGED_BRANCHES" | grep -qF "$wt_branch"; then',
        '        echo -e "  ${YELLOW}warn${RESET} Orphan worktree: $wt_dir (branch \'$wt_branch\' merged)"',
        '      fi',
        '    done < <(find "$WORKTREES_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)',
        '  fi',
        '',
        '  # Branches with gone upstream',
        '  GONE_BRANCHES=$(git branch -vv 2>/dev/null | grep ": gone\\]" | awk \'{ print $1 }\' || echo "")',
        '  if [ -n "$GONE_BRANCHES" ]; then',
        '    while IFS= read -r branch; do',
        '      [ -n "$branch" ] && echo -e "  ${YELLOW}warn${RESET} Branch without upstream: $branch"',
        '    done <<< "$GONE_BRANCHES"',
        '  else',
        '    echo -e "  ${GREEN}ok${RESET} No branches with gone upstream"',
        '  fi',
        'fi',
    ];
}
function buildSummaryAndExit(failOnDrift) {
    const lines = [
        '',
        '# -- Summary ---------------------------------------------------------------',
        'echo ""',
        'echo -e "${BOLD}Summary${RESET}"',
        'echo "Total specs: $TOTAL"',
        'if [ "$ISSUES" -gt 0 ]; then',
        '  echo -e "Issues found: ${RED}$ISSUES${RESET}"',
        'else',
        '  echo -e "Issues found: ${GREEN}0${RESET}"',
        'fi',
        '',
        '# -- Exit code -------------------------------------------------------------',
    ];
    if (failOnDrift) {
        lines.push('if [ "$FAIL_ON_ISSUES" = "true" ] && [ "$SEVERITY" != "info" ]; then', '  if [ "$ISSUES" -gt 0 ]; then', '    echo ""', '    echo -e "${RED}x Planu check failed ($ISSUES issues)${RESET}"', '    exit 1', '  fi', 'fi');
    }
    else {
        lines.push('# fail-on-issues disabled — always exits 0');
    }
    lines.push('', 'echo -e "${GREEN}ok Planu check passed${RESET}"', 'exit 0');
    return lines;
}
// -- Public API ---------------------------------------------------------------
/**
 * Generate the content of planu-check.sh for local/offline spec validation.
 * Produces the same checks as the GitHub Actions workflow, runnable without billing.
 */
export function generateLocalScript(options) {
    const { specsDir, detectDrift, failOnDrift, severityThreshold } = options;
    const lines = [
        ...buildHeader(specsDir, failOnDrift, severityThreshold, detectDrift),
        ...buildValidateSection(),
        ...(detectDrift ? buildDriftSection() : []),
        ...buildCleanupCheckSection(),
        ...buildSummaryAndExit(failOnDrift),
    ];
    return lines.join('\n') + '\n';
}
//# sourceMappingURL=local-script.js.map