* chore: add comprehensive .gitignore
* ci: update CI workflow for GitHub Flow
- Change triggers from develop to main (PRs to main + pushes to main)
- Add concurrency controls to cancel stale runs
- Update docker/build-push-action to v6
- Add descriptive job names for branch protection status checks
- Update screenshot refresh and docs sync to trigger on main pushes
* ci: update docker-publish for GitHub Flow
- Remove develop branch trigger (no more dev tag)
- Keep v* tag trigger for releases
- Update docker/build-push-action to v6
* docs: add community and governance files
- CONTRIBUTING.md with dev setup and PR guidelines
- SECURITY.md with vulnerability reporting policy
- CODE_OF_CONDUCT.md (Contributor Covenant v2.1 reference)
- PR template with conventional commits checklist
- Issue templates for bug reports and feature requests
- CODEOWNERS defaulting to @AnsoCode
- Dependabot config for npm (root, backend, frontend) and GitHub Actions
* docs: add README with badges, quick start, and contributing section
* chore: add LICENSE placeholder and open license decision issue (#100)
* docs: update CLAUDE.md for GitHub Flow branching model
- Replace develop-based Git Flow with GitHub Flow (main only)
- All branches now created off main, PRs target main
- Simplify release checklist (no develop-to-main merge step)
- Update testing strategy to reference Vitest and Playwright
- Fix docs.json reference (was mint.json)
* chore: track CLAUDE.md in version control
Remove CLAUDE.md from .gitignore so project workflow instructions
are versioned alongside the code they govern.
* docs: add MANUAL_STEPS.md for GitHub settings that require UI configuration
- Add monaco-editor to frontend deps and configure @monaco-editor/react
to use the local bundle via loader.config({ monaco }) instead of
fetching from cdn.jsdelivr.net (blocked by CSP scriptSrc: self)
- Wire editorWorker via Vite ?worker syntax — blob: URLs already
permitted by existing workerSrc CSP directive, no CSP changes needed
- fix(ci): use DOCS_REPO_TOKEN in release-please so tag creation
cascades to docker-publish.yml (GITHUB_TOKEN cannot trigger workflows)
- fix(ci): auto-merge screenshots PR via gh pr merge --auto --squash
* fix(docker): fix xx cross-compilation sysroot for node-pty and C++ modules
Three issues in the prod-deps cross-compilation stage:
1. xx-apk had `gcc` (C only) instead of `g++` — all three native modules
(bcrypt, better-sqlite3, node-pty) use C++, so libstdc++ headers must
be present in the target sysroot for xx-clang++ to link against them.
2. Missing `linux-headers` in the target sysroot — node-pty requires
<pty.h> and <termios.h> which live in the Linux kernel headers package.
3. Missing AR=xx-ar — node-gyp uses `ar` to create static archives during
the native build; without this override it falls back to the host ar
(amd64), producing wrong-arch .a files that fail at the link step.
* fix(docker): use native g++ for same-platform builds, xx-clang only for cross
xx-clang introduces sysroot flags that break node-gyp header resolution on
Alpine when TARGETARCH == BUILDARCH (e.g. the docker-validate CI job which
builds amd64-only). The native path now uses the standard g++ toolchain
(identical to what worked before the xx refactor). The cross-compilation
path (amd64 → arm64) continues to use xx-clang / xx-clang++ / xx-ar with
the target sysroot populated via xx-apk.
xx-clang introduces sysroot flags that break node-gyp header resolution on
Alpine when TARGETARCH == BUILDARCH (e.g. the docker-validate CI job which
builds amd64-only). The native path now uses the standard g++ toolchain
(identical to what worked before the xx refactor). The cross-compilation
path (amd64 → arm64) continues to use xx-clang / xx-clang++ / xx-ar with
the target sysroot populated via xx-apk.
Three issues in the prod-deps cross-compilation stage:
1. xx-apk had `gcc` (C only) instead of `g++` — all three native modules
(bcrypt, better-sqlite3, node-pty) use C++, so libstdc++ headers must
be present in the target sysroot for xx-clang++ to link against them.
2. Missing `linux-headers` in the target sysroot — node-pty requires
<pty.h> and <termios.h> which live in the Linux kernel headers package.
3. Missing AR=xx-ar — node-gyp uses `ar` to create static archives during
the native build; without this override it falls back to the host ar
(amd64), producing wrong-arch .a files that fail at the link step.
Node.js v20 uses ARMv8.1 LSE atomic instructions that the GitHub Actions
QEMU version does not support, causing SIGILL / "Illegal instruction" core
dumps when npm ci runs inside the arm64 emulated layer.
Solution: add a dedicated prod-deps build stage that runs on $BUILDPLATFORM
(amd64, native) and uses tonistiigi/xx + xx-clang to cross-compile native
modules (bcrypt, better-sqlite3, node-pty) for the TARGET architecture
without ever executing Node.js under QEMU. The final runtime stage simply
copies the pre-compiled node_modules from prod-deps.
Stage breakdown:
xx - cross-compilation helper (provides xx-clang, xx-apk)
frontend-builder - $BUILDPLATFORM, vite build (no native modules)
backend-builder - $BUILDPLATFORM, tsc compilation
prod-deps - $BUILDPLATFORM + xx-clang cross-compiles for $TARGET
final - TARGET platform, no compilation at all
- Add docker/setup-qemu-action@v3 to docker-publish.yml (was missing,
causing multi-platform builds to hang indefinitely)
- Add platforms: linux/amd64,linux/arm64 to build-push-action step
- Optimize Dockerfile with --platform=$BUILDPLATFORM on builder stages
so TypeScript compilation runs at native amd64 speed; only the lean
npm ci --omit=dev step runs under QEMU in the final stage, compiling
the three native modules (bcrypt, better-sqlite3, node-pty) for the
correct target architecture — reduces arm64 build time from 6+ hours
to ~15-30 minutes