> ## Documentation Index
> Fetch the complete documentation index at: https://docs.swiftaiboilerplate.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Scripts Reference

> Helper scripts shipped in scripts/ for testing, App Store 4.3 hardening, rebranding, config generation, and manifest validation (v2.2.0).

The boilerplate ships five helper scripts in `scripts/`. Each is listed below with its real flags and behavior, verified against the script source.

| Script                            | Purpose                                                            |
| --------------------------------- | ------------------------------------------------------------------ |
| `run-tests.sh`                    | Test runner with coverage measurement                              |
| `appstore-43-audit.sh`            | App Store Guideline 4.3(a) Release-binary audit gate (new in v2.2) |
| `rebrand-design-system-prefix.sh` | Rename the `SAI` design-system prefix (new in v2.2)                |
| `update-config.sh`                | Generate `Configuration.swift` from `Secrets.xcconfig`             |
| `validate-template-manifest.sh`   | Validate `template.manifest.json` against the repo (new in v2.2)   |

## run-tests.sh

**Location:** `scripts/run-tests.sh`

Test runner with optional coverage measurement. Run from the project root. With no flags it runs the app test target via `xcodebuild test` against the `SwiftAIBoilerplatePro` scheme; with `--package NAME` it runs `swift test` inside `Packages/NAME` instead.

<Tabs>
  <Tab title="Basic Usage">
    ```bash theme={null}
    # Run the app test target
    ./scripts/run-tests.sh

    # Run with coverage
    ./scripts/run-tests.sh --coverage

    # Run and open the HTML report
    ./scripts/run-tests.sh --coverage --open
    ```
  </Tab>

  <Tab title="Package Testing">
    ```bash theme={null}
    # Test a specific package (swift test in Packages/NAME)
    ./scripts/run-tests.sh --package Core
    ./scripts/run-tests.sh --package Networking
    ./scripts/run-tests.sh --package Storage

    # With coverage
    ./scripts/run-tests.sh --package Core --coverage
    ```
  </Tab>

  <Tab title="Verbose">
    ```bash theme={null}
    # Show full xcodebuild output (skips xcpretty)
    ./scripts/run-tests.sh --verbose

    # Print usage
    ./scripts/run-tests.sh --help
    ```
  </Tab>
</Tabs>

**Flags:**

* `--coverage` — Enable code coverage and generate the report
* `--open` — Open the HTML coverage report in the browser
* `--package NAME` — Test a single package via `swift test`
* `--verbose` — Show detailed `xcodebuild` output (otherwise piped through `xcpretty` when available)
* `--help` — Show usage and exit

**Output (with `--coverage`, full-app run only):**

* Console test results
* `coverage-report.txt` — text summary
* `coverage-report.html` — detailed HTML report

<Note>
  The script's internal `COVERAGE_THRESHOLD` (85%) only prints a pass/warn line; it does not fail the run. The enforced gate lives in CI (see [CI/CD Commands](#cicd-commands)). The full app run uses the `Boilerplate.xctestplan` workspace test plan, which executes \~598 tests across the 12 package test targets plus the app unit and UI test suites in one pass.
</Note>

## appstore-43-audit.sh

**Location:** `scripts/appstore-43-audit.sh`

New in v2.2. Builds the app in **Release** configuration, then runs a `strings` audit over the main executable and the app-owned bundle, failing the build if any un-rebranded production fingerprint survives. This is the headline App Store Guideline 4.3(a) gate: it stops you from shipping a binary that still looks like the starter template.

The risky-string patterns (`SwiftAI`, `Boilerplate`, `api.example.com`, `DesignSystem/SAI`, and more) are loaded from `template.manifest.json` so the script, CI, and agent prompts never diverge; an inline fallback list is used only for detached copies.

```bash theme={null}
# Run the full Release-binary audit from the project root
bash scripts/appstore-43-audit.sh
```

Beyond the binary scan, it also checks **configuration readiness** and fails until you:

* replace the starter `BrandConfig.appDisplayName` (`"App Name"`),
* set production `privacyPolicyURLString`, `termsOfServiceURLString`, and `subscriptionTermsURLString` in `BrandConfig`,
* rename the starter app bundle ID by editing `APP_BUNDLE_ID` (`com.berkin.SwiftAIBoilerplatePro`) in `Config/App.xcconfig` — every target's `PRODUCT_BUNDLE_IDENTIFIER` derives from it — and
* remove bundled generic/demo legal/showcase markdown.

It exits non-zero on any blocking app-owned hit and prints `PASS:` when clean. Override the scheme, destination, or derived-data paths via `AUDIT_SCHEME`, `AUDIT_DESTINATION`, `AUDIT_DERIVED_DATA`, and `AUDIT_PACKAGE_CACHE` env vars.

<Note>
  The deeper hardening workflow (binary audit, branding/identity map, App Review Notes template, per-module removal) lives in `docs/checklists/APP_STORE_4_3_HARDENING.md`, with prompt packs in `docs/prompts/AppStore4_3Hardening.prompts.md`. The matching standalone **App Generator** that produces a 4.3-safe app from this template is a separate product (coming soon) — see the [License & Updates](/pages/reference/license) page.
</Note>

## rebrand-design-system-prefix.sh

**Location:** `scripts/rebrand-design-system-prefix.sh`

New in v2.2. Renames the `SAI` design-system prefix throughout `Packages/DesignSystem` — both textual occurrences in `.swift`/`.md` files and the `SAI*`-named source files themselves. Useful for clearing the `DesignSystem/SAI` fingerprint flagged by the 4.3 audit.

```bash theme={null}
# Dry run (default): list textual matches and the files that would be renamed
bash scripts/rebrand-design-system-prefix.sh SAI YourPrefix

# Apply the rename after committing or stashing your work
bash scripts/rebrand-design-system-prefix.sh SAI YourPrefix --apply
```

**Arguments:** `OLD_PREFIX` (default `SAI`), `NEW_PREFIX` (required), `MODE` (`--dry-run` default, or `--apply`). The new prefix must be a Swift-style identifier starting with an uppercase letter.

<Warning>
  `--apply` rewrites files in place. Commit or stash first, then re-run tests and `scripts/appstore-43-audit.sh` before submitting.
</Warning>

## update-config.sh

**Location:** `scripts/update-config.sh`

Generates `SwiftAIBoilerplatePro/Generated/Configuration.swift` from `Config/Secrets.xcconfig`. Run it manually after filling in your keys. Placeholder values containing `YOUR` are skipped, so a fresh clone still builds and runs with `MockAuthClient` and `EchoLLMClient`.

```bash theme={null}
# Generate Configuration.swift from Config/Secrets.xcconfig
bash scripts/update-config.sh
```

The generated `AppConfiguration` enum exposes a `static let` for each configured key and an `isConfigured(_:)` helper. Recognized keys: `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `REVENUECAT_API_KEY`, `RC_ENTITLEMENT_ID`, `PROXY_BASE_URL`, `PROXY_PATH`, `ONESIGNAL_APP_ID`. See the [Configuration reference](/pages/reference/config) for details.

<Warning>
  This writes real API keys into a committed-by-default path. Do NOT commit `Configuration.swift` after running it. Install the pre-commit hook to block accidental commits: `git config core.hooksPath .githooks`.
</Warning>

## validate-template-manifest.sh

**Location:** `scripts/validate-template-manifest.sh`

New in v2.2. Validates `template.manifest.json` (the machine-readable single source of truth for identity surface, module graph, config schema, fingerprints, and recipes) against the actual repository.

```bash theme={null}
# Validate the manifest from the project root
bash scripts/validate-template-manifest.sh
```

It checks that:

* every path referenced by the manifest exists,
* each module's manifest-declared dependencies match its `Package.swift`,
* the manifest fingerprint list is a superset of the audit script's fallback list, and
* each brand anchor resolves to exactly one marked line.

It prints `template.manifest.json OK` on success or one `FAIL:` line per problem (exit 1). This runs as the `Template Manifest` job in CI.

## Supabase Scripts

### Deploy Edge Function

```bash theme={null}
# Login
supabase login

# Link project
cd supabase
supabase link --project-ref YOUR_REF

# Set secrets
supabase secrets set OPENROUTER_API_KEY=sk-or-v1-YOUR_KEY

# Deploy
supabase functions deploy ai

# Test
curl https://YOUR_PROJECT.supabase.co/functions/v1/ai
```

### Run Migrations

```bash theme={null}
# Push all migrations
supabase db push

# Create new migration
supabase migration new your_migration_name

# Reset database (DANGER!)
supabase db reset
```

### Local Development

```bash theme={null}
# Start local Supabase
supabase start

# Run functions locally
supabase functions serve

# Stop local Supabase
supabase stop
```

## Xcode Build Scripts

### Clean Build

```bash theme={null}
# In Xcode
⌘ + Shift + K

# Or terminal
xcodebuild clean \
  -scheme SwiftAIBoilerplatePro \
  -configuration Debug
```

### Archive

```bash theme={null}
# Terminal archive
xcodebuild archive \
  -scheme SwiftAIBoilerplatePro \
  -archivePath ./build/SwiftAIBoilerplatePro.xcarchive
```

### Run Tests

One `xcodebuild test` against the scheme runs the whole `Boilerplate.xctestplan` (all 12 package test targets + the app suites, \~598 tests):

```bash theme={null}
xcodebuild test \
  -project SwiftAIBoilerplatePro.xcodeproj \
  -scheme SwiftAIBoilerplatePro \
  -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=26.2' \
  -enableCodeCoverage YES
```

## Git Workflows

### Pre-commit Checks

The repo ships a pre-commit hook that blocks committing a generated `Configuration.swift`. Install it once:

```bash theme={null}
git config core.hooksPath .githooks
```

Run the same checks CI runs before pushing:

```bash theme={null}
# Lint (strict)
swiftlint lint --strict

# Tests with coverage
./scripts/run-tests.sh --coverage

# Validate the template manifest
bash scripts/validate-template-manifest.sh
```

Before an App Store submission, also run the 4.3 audit gate:

```bash theme={null}
bash scripts/appstore-43-audit.sh
```

### Branch Management

```bash theme={null}
# Create feature branch
git checkout -b feature/your-feature

# Commit with message
git commit -m "feat: your feature description"

# Push and create PR
git push origin feature/your-feature
```

## Package Management

### Update Dependencies

```bash theme={null}
# In Xcode
File → Packages → Update to Latest Package Versions

# Or terminal
xcodebuild -resolvePackageDependencies
```

### Reset Package Cache

```bash theme={null}
# In Xcode
File → Packages → Reset Package Caches

# Or terminal
rm -rf ~/Library/Caches/org.swift.swiftpm
rm -rf ~/Library/Developer/Xcode/DerivedData
```

## Common Commands

### Development

```bash theme={null}
# Open project
open SwiftAIBoilerplatePro.xcodeproj

# Run app (requires Xcode)
xcodebuild -scheme SwiftAIBoilerplatePro

# Build only
xcodebuild build -scheme SwiftAIBoilerplatePro
```

### Configuration

```bash theme={null}
# Copy config template
cp Config/Secrets.example.xcconfig Config/Secrets.xcconfig

# Edit config
nano Config/Secrets.xcconfig
# or
open -a Xcode Config/Secrets.xcconfig
```

### Cleaning

```bash theme={null}
# Clean derived data
rm -rf ~/Library/Developer/Xcode/DerivedData

# Clean build folder
xcodebuild clean

# Reset simulators
xcrun simctl erase all
```

## CI/CD Commands

### GitHub Actions

Workflows in `.github/workflows/`:

**Main CI (`ci.yml`)** — runs on push and pull request:

```text theme={null}
- Template Manifest    validate-template-manifest.sh
- Secret Scan          Gitleaks
- Build & Test (iOS 26.2)   xcodebuild test (iPhone 17 Pro, OS=26.2) + coverage gate
- Build & Test (iOS 18.6 fallback path)   pre-iOS-26 compile/run, no coverage gate
- SwiftLint             swiftlint lint --strict
```

The coverage gate enforces the `MINIMUM_COVERAGE` env value (currently `25`) and fails the build below it; it is computed over product targets only.

**Coverage Report (`coverage-report.yml`)** — runs weekly (Mondays 09:00 UTC) and on manual dispatch:

```text theme={null}
- Generate detailed coverage (text + JSON)
- Build an HTML coverage report
- Open a GitHub issue if coverage is low
```

**Trigger manually:**

```text theme={null}
GitHub UI → Actions → Select workflow → Run workflow
```

## Quick Reference

<AccordionGroup>
  <Accordion title="Run Tests Locally">
    ```bash theme={null}
    ./scripts/run-tests.sh --coverage --open
    ```
  </Accordion>

  <Accordion title="Deploy Backend">
    ```bash theme={null}
    cd supabase
    supabase functions deploy ai
    ```
  </Accordion>

  <Accordion title="Clean Everything">
    ```bash theme={null}
    xcodebuild clean
    rm -rf ~/Library/Developer/Xcode/DerivedData
    rm -rf ~/Library/Caches/org.swift.swiftpm
    ```
  </Accordion>

  <Accordion title="Check Coverage">
    ```bash theme={null}
    ./scripts/run-tests.sh --coverage
    open coverage-report.html
    ```
  </Accordion>

  <Accordion title="App Store 4.3 Pre-submission Audit">
    ```bash theme={null}
    bash scripts/appstore-43-audit.sh
    ```
  </Accordion>
</AccordionGroup>

## Related Resources

<CardGroup cols={2}>
  <Card title="Testing Guide" href="/pages/guides/testing">
    Testing strategies
  </Card>

  <Card title="Deployment" href="/pages/guides/deployment">
    Production deployment
  </Card>

  <Card title="Supabase Setup" href="/pages/guides/supabase-setup">
    Backend deployment
  </Card>

  <Card title="Configuration" href="/pages/reference/config">
    Config reference
  </Card>

  <Card title="License & Updates" href="/pages/reference/license">
    Pricing, lifetime updates, and the App Generator (coming soon)
  </Card>
</CardGroup>
