# dependencies
node_modules/
.pnp
.pnp.js

# builds
dist/
.next/
# The desktop build's own output directory, so it cannot collide with a dev server.
.next-desktop/
out/
build/
*.tsbuildinfo

# --- secrets ---------------------------------------------------------------
#
# One folder for everything credential-shaped that has to live in the checkout:
# `.env.migration`, `.env.oci`, and any key a cloud console downloaded here.
# See secrets/README.md.
#
# `.env.local` cannot move — Next.js only reads it from the app directory — and
# neither can ~/.oci or ~/.ssh, so the patterns below stay as a second layer.
# A single directory rule is one edit away from being wrong.
#
# Contents rather than the directory itself (`/secrets/*`, not `/secrets/`), so
# the README can be un-ignored: git does not descend into an excluded directory,
# and a negation inside one never matches.
/secrets/*
!/secrets/README.md

.env
.env.local
.env*.local
.env.migration
.env.oci
oci-launch-retry.log

# Private keys. Cloud consoles download these straight to whatever directory the
# browser last used, which is often a checkout — and an OCI API key or SSH key
# committed to a public repo is a full account compromise, not a near miss.
*.pem
*.key
*_rsa
*_ed25519
id_*
# Public halves are not secret — they exist to be published — but they still do
# not belong in a checkout, and an un-ignore rule for them re-included a key
# from secrets/ that the directory rule had correctly excluded.
*.pub
local-dev/

# demo captures (regenerate locally; README embeds added later)
docs/demo/

# graphify build artifacts
graphify-out/

# playwright
apps/web/test-results/
apps/web/e2e/.auth/

# Serwist (generated at next build)
apps/web/public/sw.js

# Pitch site assets (copied from apps/web/public at build)
apps/pitch/public/
apps/web/public/sw.js.map
apps/web/public/swe-worker*

# pdf.js worker (copied from pdfjs-dist by scripts/copy-pdf-worker.mjs)
apps/web/public/pdf.worker.min.mjs

# --- the Windows Ink recogniser helper -------------------------------------
#
# The helper is C# source in `apps/desktop/native/ink-recogniser/`; what is
# ignored is what `dotnet` produces — `bin/` and `obj/` for a local build, and
# `win-<arch>/` for the two published self-contained executables
# (`scripts/build-ink-recogniser.mjs`, ~14 MB each). Those are packaging inputs,
# rebuilt by the build rather than reviewed, and a 14 MB binary in the history of
# a source repository is not something a later commit can take back.
apps/desktop/native/ink-recogniser/bin/
apps/desktop/native/ink-recogniser/obj/
apps/desktop/native/ink-recogniser/win-*/

# python
__pycache__/
*.py[cod]
.venv/
venv/
*.egg-info/
.pytest_cache/

# os / editor
.DS_Store
.idea/
.vscode/
*.log

# supabase
supabase/.branches
supabase/.temp
.conda-plugin-tools
# Phase-5 E2EE pre-drop backups (contain key material — never commit)
backups/

# Android TWA signing keys — never commit
*.jks
*.keystore
apps/web/twa/android-keystore.jks

# --- Android TWA: ignore the build output, never the project -----------------
#
# This block used to ignore `apps/web/twa/app/` — the Gradle *module source*
# (AndroidManifest.xml, the Java classes, every `res/` file) — along with
# `gradle/`, `gradlew`, `gradlew.bat`, `build.gradle`, `settings.gradle` and
# `gradle.properties`. The result was that `git ls-files apps/web/twa` returned
# only the README and `twa-manifest.json`, while
# the TWA workflow (now retired) claimed to build "from the committed
# Bubblewrap project": nothing under the Android tree had ever been reviewed or
# could be reproduced from a clone. `bubblewrap update` calls
# `TwaGenerator.removeTwaProject()` and then regenerates the whole module from
# the CLI's bundled template, so the next release would also have replaced
# whatever was on disk — the ignore rule was protecting a source tree from
# being committed and simultaneously guaranteeing it would be overwritten.
#
# The correct ignore is the *output* directory. Bubblewrap and Gradle write
# everything they produce under a `build` directory — `app/build/` for the
# module, `build/` at the project root (the generic `build/` rule above already
# matches both at any depth; the explicit line below keeps that true for someone
# reading only this block) — and `.gradle/` for the Gradle daemon's local state.
# `apps/web/twa/app/src/**`, `apps/web/twa/app/build.gradle`,
# `apps/web/twa/build.gradle`, `apps/web/twa/settings.gradle`,
# `apps/web/twa/gradle.properties`, the `gradle/` wrapper (jar + properties) and
# `gradlew` / `gradlew.bat` are the project, and are committed on purpose.
apps/web/twa/app/build/
apps/web/twa/build/
apps/web/twa/.gradle/

# Signed and unsigned build artifacts. `app-release-bundle.aab` had no rule at
# all before this, so the one output the Play upload path exists to produce was
# the only one that could have been committed by accident.
*.apk
*.apk.idsig
*.aab

# Bubblewrap records the SHA-1 of the `twa-manifest.json` it last generated the
# project from, and `bubblewrap build` compares it: when the file is missing or
# stale it stops and asks whether to regenerate. The release workflow writes it
# before building, and it is derived from a committed file, so it is generated
# state rather than source.
apps/web/twa/manifest-checksum.txt

# The Play Store listing icon Bubblewrap leaves beside the project. Nothing in
# the Gradle project or the manifest references it (the icons the APK actually
# carries are generated into `app/src/main/res/mipmap-*`), so it is an upload
# artifact, not source.
apps/web/twa/store_icon.png

# playwright (root)
test-results/
.design-sync

# OS junk
desktop.ini
Thumbs.db
.DS_Store
.vercel

# W&B offline runs land beside whatever started them.
wandb/

# generated by apps/web/scripts/build-embedding-worker.mjs
apps/web/public/embedding-worker.js
apps/web/public/ort-wasm-*

# local diagnostics probes
.scratch/
