Project-level AI-tool instruction files (CLAUDE.md, AGENTS.md,
GEMINI.md, .cursorrules, .windsurfrules, .aider.conf.yml) are
operator-scoped working notes, not project artifacts. Other
contributors don't need them, and committing them conflates
operator preferences with shared project conventions.
CLAUDE.md remains on the local disk (untracked) so Claude Code
keeps loading it for this checkout; new clones simply won't have
it, which is the desired state.
- rename .forgejo/workflows/ to .gitea/workflows/ (git mv preserves
history); Gitea Actions reads either path, but the directory now
matches the active platform
- collapse ANDROID_STORE_PASSWORD + ANDROID_KEY_PASSWORD into a
single ANDROID_KEYSTORE_PASSWORD secret (PKCS12 keystores require
the two passwords to be identical, so the duplication carried no
information); build.gradle.kts still reads two env vars to stay
format-agnostic, both now sourced from the same secret in CI
- ignore android/*.keystore, android/*.keystore.*, android/*.jks,
android/keystore.properties so the regenerated signing material
never reaches a remote on accident
- update prose references from Forgejo to Gitea in CLAUDE.md and
the docs; the historical "migrated from Forgejo" note in CLAUDE.md
is kept intentionally; forgejo/upload-artifact@v3 action refs are
left untouched (canonical artifact action, resolves cleanly under
Gitea Actions)
Operator side: ANDROID_KEY_ALIAS, ANDROID_KEYSTORE_PASSWORD, and
ANDROID_KEYSTORE_B64 secrets registered in Gitea before this lands.
Previous commit (0b72827) accidentally swept the local
android/.gradle, android/build, android/app/build, and
android/local.properties into the index via `git add android/`.
Root .gitignore only had entries for flutter_client/android/
paths, not the new native android/ tree.
Removes the cached files via `git rm --cached` and extends
.gitignore to cover the native Android Studio output dirs
(.gradle, .kotlin, .idea, build, app/build, local.properties,
*.iml). Source code is unaffected — only build-output and IDE
artifacts get untracked.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final phase of the in-app update flow. release.yml on tag pushes
fetches the APK that flutter.yml is attaching to the same release,
drops it into client/ in the build context, and the Dockerfile's
COPY client/ /app/client/ bakes it into the image.
### How it sequences
flutter.yml and release.yml both trigger on tag pushes and run in
parallel on different runners (flutter-ci vs go-ci). flutter.yml
typically finishes APK build + release attachment in 2-5 min.
release.yml polls the release page for up to 15 min for the APK to
appear, then proceeds. If the APK never lands (flutter.yml failure,
network hiccup), release.yml emits a warning and ships the image
without the bundled APK — server returns 404 from /api/client/version,
banner stays hidden, manual download from the release page still
works. Graceful degradation, not a blocker.
### Repo shape
- client/.gitkeep + client/README.md so the directory exists in git
and the COPY in the Dockerfile always finds something to copy
- .gitignore excludes client/minstrel.apk + .version so accidental
commits don't bloat the repo
- Dockerfile: COPY --chown=minstrel:minstrel client/ /app/client/
### Why polling vs cross-workflow trigger
Forgejo Actions' workflow_run support varies by runner version; the
polling approach is universally compatible. If/when we standardize on
a runner that handles workflow_run cleanly, the polling step can
become a `needs:` dependency.
Closes#397.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Workspace flatten brought these operator-scoped state dirs (Claude
Code per-machine settings and remember-skill memory artifacts) into
the repo's working tree. Neither belongs in git — the canonical
project memory lives under ~/.claude/projects/ outside the repo.
Agent-authored design specs and implementation plans are kept local
on the working machine; the canonical record lives in commit messages
and the running code. The 48 historical files remain in git history
and can be retrieved via git checkout <sha> -- docs/superpowers/ if
ever needed; they just stop accruing on the dev tip.
iOS + Android targets only; desktop disabled (per spec, Tauri-wrapped
SvelteKit handles desktop in v1.1). Riverpod + dio + just_audio +
audio_service + go_router pinned in pubspec. Smoke test confirms the
ProviderScope wiring boots a Material app.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First pass of the web UI design doc from the M1 close-out brainstorm.
Covers the stack (SvelteKit static + Go embed), auth model
(cookie + bearer from one endpoint), /api/* surface, shell layout
(sidebar + bottom player), first-cut feature scope, and how later
web UI work threads into M2–M5 alongside each backend milestone
instead of landing as a post-hoc M6.
Also ignores the local .superpowers/ brainstorming companion cache.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>