RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/CLAUDE.md/kurikomi-labs/komi-store

CLAUDE.md

CLAUDE.md
CLAUDE.mdroot

Quality

78/100

Scores the file, not the repository.

Length

1,396 words

15 headings · 3 code blocks

Repository

17k

— · pushed 5 days ago

Last changed

3 days ago

First indexed 3 days ago.
kurikomi-labs/komi-store/CLAUDE.mdRawGitHub
1# Komi Store
2 
3Cross-platform app store for GitHub + Codeberg + Forgejo releases. **Kotlin Multiplatform** + **Compose Multiplatform**. Android (min API 26) + Desktop (JVM: Win/macOS/Linux). Package `zed.rainxch.githubstore`. Version 1.8.3 (code 18). Target SDK 36.
4 
5## Build
6 
7```bash
8./gradlew :composeApp:assembleDebug # Android
9./gradlew :composeApp:run # Desktop dev
10./gradlew :composeApp:packageExe :composeApp:packageMsi # Win installer
11./gradlew :composeApp:packageDmg :composeApp:packagePkg # macOS
12./gradlew :composeApp:packageDeb :composeApp:packageRpm # Linux
13./gradlew build # full
14```
15 
16JDK 21+. Android SDK for Android.
17 
18## Structure
19 
20```text
21composeApp/ # entry points, navigation, DI wiring (commonMain / androidMain / jvmMain)
22core/
23 domain/ # interfaces, models, use cases (no framework deps)
24 data/ # repos, Ktor, Room, Koin, platform impls
25 presentation/ # Material 3 theme + reusable components + 14-locale strings
26feature/
27 apps auth details dev-profile favourites homeP profile recently-viewed search starred tweaks
28build-logic/convention/ # convention plugins
29```
30 
31Each feature: up to 3 sub-modules (`domain/`, `data/`, `presentation/`). `favourites`, `starred`, `recently-viewed` are presentation-only.
32 
33## Architecture
34 
35Clean Architecture + MVVM. Layers: **Domain** (contracts), **Data** (Ktor + Room + Koin DI), **Presentation** (ViewModels with `StateFlow`/`Channel`, Compose).
36 
37### State pattern (every screen)
38 
39```kotlin
40class XViewModel : ViewModel() {
41 private val _state = MutableStateFlow(XState())
42 val state = _state.asStateFlow() // or .stateIn(WhileSubscribed)
43 private val _events = Channel<XEvent>()
44 val events = _events.receiveAsFlow()
45 fun onAction(action: XAction) { ... }
46}
47```
48 
49`State` = data class. `Action` = sealed (user input). `Event` = sealed (one-off effects).
50 
51### Navigation
52 
53`@Serializable` sealed interface `GithubStoreGraph` in `composeApp/.../app/navigation/`. Routes: `HomeScreen`, `SearchScreen`, `AuthenticationScreen`, `ProfileScreen`, `TweaksScreen`, `FavouritesScreen`, `StarredReposScreen`, `RecentlyViewedScreen`, `AppsScreen`, `OnboardingScreen`, `ExternalImportScreen`, `MirrorPickerScreen`, `StarredPickerScreen`, `SkippedUpdatesScreen`, `HiddenRepositoriesScreen`, `WhatsNewHistoryScreen`, `AnnouncementsScreen`, `HostTokensScreen`, `DetailsScreen(repositoryId, owner, repo, isComingFromUpdate, sourceHost)`, `DeveloperProfileScreen(username)`. `DetailsScreen.sourceHost` is non-null for Codeberg / Forgejo / custom-forge repos — routes all `DetailsRepository` calls through `ForgejoClientRegistry` instead of the GitHub-backed default path.
54 
55### DI
56 
57Koin. Feature modules in `data/di/SharedModule.kt`. ViewModels in `composeApp/.../app/di/ViewModelsModule.kt` (`viewModelOf(::X)` or explicit `viewModel { ... }`). Wired in `initKoin.kt`.
58 
59## Core repositories (`core/domain`)
60 
61`FavouritesRepository`, `StarredRepository`, `InstalledAppsRepository`, `SeenReposRepository`, `HiddenReposRepository`, `SearchHistoryRepository`, `TweaksRepository`, `AuthenticationState`, `ThemesRepository`, `ProxyRepository`, `RateLimitRepository`, `ExternalImportRepository`, `TelemetryRepository`, `HostTokenRepository` (per-host PATs, KSafe-encrypted). Network: `ForgejoApiClient` + `ForgejoClientRegistry` (per-host Ktor clients, thread-safe via Mutex, proxy-aware, closes cached engines on shutdown / proxy change). Util: `AssetVariant` (token/glob/stem fingerprinting), `assetPlatformOf`, `RepoIdCodec` (23-bit host fingerprint + 40-bit raw id packed into the existing 64-bit `repoId` slot — sign bit = foreign source), `RepositoryUrlParser` (recognises GitHub + Codeberg + gitea.com + git.disroot.org + user-added forge hosts). System interfaces: `Installer`, `InstallerStatusProvider`, `PackageMonitor`, `SystemInstallSerializer`.
62 
63## Tech
64 
65Kotlin 2.3.10, Compose Multiplatform 1.10.3, Ktor 3.4.0, Room 2.8.4, Koin 4.1.1, kotlinx.serialization 1.10.0, DataStore 1.2.0, Landscapist 2.9.5, Kermit 2.0.8, MOKO Permissions 0.20.1, Navigation Compose 2.9.2, multiplatform-markdown-renderer 0.39.2, Shizuku 13.1.5, WorkManager 2.11.1, kotlinx.datetime 0.7.1. Versions in `gradle/libs.versions.toml`.
66 
67## Convention plugins (`build-logic/convention/`)
68 
69`convention.kmp.library` (domain/data), `convention.cmp.library` (core/presentation), `convention.cmp.feature` (feature presentation), `convention.cmp.application` (main app), `convention.room`, `convention.buildkonfig`.
70 
71## Adding a feature
72 
731. `feature/<name>/{domain,data,presentation}/` with appropriate convention plugin
742. `include` in `settings.gradle.kts`
753. Domain interfaces → impl + Koin module in `data/di/SharedModule.kt` → ViewModel + Screen
764. Route in `GithubStoreGraph.kt` + wire in `AppNavigation.kt` + register Koin in `initKoin.kt`
77 
78## Key configuration
79 
80- **GitHub OAuth:** `GITHUB_CLIENT_ID` in `local.properties`. Deep links: `githubstore://auth` (web-OAuth handoff), `githubstore://callback` (legacy device-flow leftover), `githubstore://repo`, `githubstore://apps`.
81- **Shizuku (Android):** silent install via `ShizukuProvider` → AIDL → `pm install -S`. Fallback to standard installer on failure.
82- **Desktop logs:** `CrashReporter` (first line of `DesktopApp.main`) tees stdout/stderr to rotating `session.log` + writes `crash-<ts>.log` on uncaught. Paths: `~/Library/Logs/GitHub-Store/` (macOS), `%LOCALAPPDATA%/GitHub-Store/logs/` (Win), `$XDG_STATE_HOME/GitHub-Store/logs/` (Linux). Android = Logcat.
83- **macOS distribution:** Homebrew cask in tap `openhub-store/tap` (separate repo `homebrew-tap`). `brew install --cask github-store`. Unsigned at present — user must `xattr -dr com.apple.quarantine /Applications/GitHub-Store.app` after install. CI builds `.dmg` + `.pkg` on every push to `generate-installers`; tap cask updates automatically on release.
84- **`X-GitHub-Token` header:** Client attaches when `TokenStore.currentToken()` is non-null on `/v1/search`, `/v1/search/explore`, `/v1/repo`, `/v1/releases`, `/v1/readme`, `/v1/user`. Backend re-sends as `Authorization: token $token` to GitHub. Without it, backend round-robins a 4-token service pool. Upstream 401 remapped to backend `502` (handled like "GitHub unreachable" — fall back via `shouldFallbackToGithubOrRethrow`). `429` = no fallback (same wall), only backoff. `UnauthorizedInterceptor` only on direct-GitHub client; `AuthenticationStateImpl` debounces consecutive 401s by token snapshot.
85- **Auth flow (web-OAuth-first):** Primary path is web OAuth with PKCE + handoff. `feature/auth/data/crypto/PkceGenerator` mints `(state, codeVerifier, codeChallenge)`; `WebAuthApi.register` POSTs verifier + challenge + state to `https://github-store.org/auth/register` (Cloudflare Worker stashes them in Workers KV) and returns `authUrl`. User opens it, authorizes on `github.com`, GitHub redirects to `github-store.org/auth/callback?code&state` where the Worker exchanges the code via `api.github-store.org` (backend stores `(handoffId → access_token)` for 60s in Postgres with atomic `DELETE…RETURNING`), then bounces back to `githubstore://auth?h=<handoffId>`. App reads handoff via `WebAuthApi.consumeHandoff` (GETDEL semantics). Secondary path: device flow via backend `/v1/auth/device/start` + `/poll`, `AuthPath` (`Backend`|`Direct`) tracked in `SavedStateHandle`, only escalates `Backend → Direct` on infra errors. Tertiary: paste a Personal Access Token (`signInWithPat` — validates against `/user`, persists optimistically when GitHub unreachable). Backend rate limits: 10 device-starts/hr, 200 device-polls/hr per IP. Endpoints in `core/data/network/BackendEndpoints.kt` (`BACKEND_ORIGIN`, `WEB_ORIGIN`).
86- **Windows installer signing (SignPath Foundation):** CI workflow `.github/workflows/build-desktop-platforms.yml` job `sign-windows` after every push to `generate-installers` branch. Action pinned to commit SHA (not `@v2`). Secrets: `SIGNPATH_API_TOKEN`, `SIGNPATH_ORGANIZATION_ID` (`1ecf111e-...`). Variable `SIGNPATH_SIGNING_POLICY_SLUG` = `test-signing` until prod cert issued; flip to `release-signing`. Project slug `GitHub-Store`, artifact config slug `initial`. Unsigned artifact deleted post-sign; only `windows-installers-signed` reaches the draft release.
87- **WinGet publish:** `.github/workflows/winget-publish.yml` fires on `release: [released]`. Action `vedantmgoyal9/winget-releaser@main`. Secret `WINGET_TOKEN` = PAT with `Contents+Pull requests: write` on `OpenHub-Store/winget-pkgs` (fork of `microsoft/winget-pkgs`). Pin `fork-user: OpenHub-Store` explicitly so the action doesn't infer from token owner.
88- **Forges (Codeberg / Forgejo / Gitea):** `ForgejoApiClient` per host (60s req / 30s connect+socket timeouts, exponential retry on 5xx + IOException). `ForgejoClientRegistry.clientFor(host)` cached + Mutex-guarded. Direct-to-forge — no backend mediator. `RepoIdCodec` packs host fingerprint into `repoId` so the existing GitHub-shaped schema survives. README via `/contents/README.md?ref={branch}` (Forgejo has NO `/readme` endpoint). License sniffed from `/contents/LICENSE` regex against SPDX headers. Downloads aggregated by summing `asset.download_count` across releases.
89- **Per-host PATs:** `HostTokenRepository` stores `{host, token, label, createdAt}` rows AES-256-GCM encrypted via KSafe. `HostTokenInterceptor` (Ktor plugin) injects `Authorization: token $pat` on matched host. `HostNames.apiHostToTokenHost` maps `api.github.com → github.com` so the GitHub-direct client looks up the right PAT. UI at `Tweaks → Access Tokens` (`HostTokensScreen`).
90- **KSafe:** AES-256-GCM with hardware-backed Keystore on Android. Wraps every persisted credential / pref via `core/data/secure/KSafeSafe.kt` extension funcs (`safeGet`, `safePut`, `safeDelete`, `safeGetFlow`) — surface log + return null/false on transient failure instead of throwing through coroutine scopes.
91- **Translation providers:** `TranslationProvider` enum = `GOOGLE`, `YOUDAO`, `LIBRE_TRANSLATE`, `DEEPL`, `MICROSOFT`. Each per-provider config persisted via `TweaksRepository` (KSafe-encrypted). `TranslationRepositoryImpl.resolveTranslator()` picks the impl. LibreTranslate defaults to the bundled `translate.disroot.org` mirror when user URL pref blank. DeepL auto-routes `:fx`-suffixed keys to `api-free.deepl.com`. Microsoft uses No-Trace by default — text never stored, never used for training.
92- **Gradle:** Config + build cache enabled. 4GB Gradle heap, 3GB Kotlin daemon. Official Kotlin style.
93 
94## Active skills (apply on matching domain)
95 
96- **caveman** — session default, terse output.
97- **karpathy-guidelines** — anti-overcomplication, minimal diffs, surface assumptions, verifiable success criteria. Every coding task.
98- **one-skill-to-rule-them-all** — watch for skill-capture opportunities during multi-step work.
99- **gsd-inbox** - Triage open GitHub issues + PRs against templates. Our exact pattern — automate the "check issue #N, draft reply, ship fix" loop.
100- **gsd-ship** - Create PR + review + prep for merge. Every task ends here.
101- **gsd-quick** - Trivial task with atomic commits + state tracking. Matches our small-commit policy.
102- **gsd-debug** - Systematic debugging with persistent state across context resets. For bug-hunt cycles.
103- **android-* skills** (`~/.claude/skills/android/`) — auto-fire by description match; apply when in matching domain:
104 - `android-compose-ui` — composables, recomposition, animations, modifiers, design system
105 - `android-data-layer` — repos, DTOs, Room, Ktor, mappers
106 - `android-di-koin` — Koin module setup, ViewModel injection
107 - `android-error-handling` — Result wrapper, typed errors
108 - `android-module-structure` — feature-layered modules, convention plugins
109 - `android-navigation` — type-safe Compose nav
110 - `android-presentation-mvi` — State/Action/Event, Root/Screen split, UiText, SavedStateHandle
111 - `android-testing` — testing patterns
112 
113## Conventions
114 
115- Packages `zed.rainxch.{module}.{layer}`
116- Private state fields prefix `_state`
117- Sealed routes/actions/events
118- Repository pattern: interface in `domain/`, impl in `data/`
119- Source sets: `commonMain` shared, `androidMain`, `jvmMain`
120- **No KDoc, no inline comments** unless the user explicitly asks. No function/class docs. Inline only for non-obvious invariants, tricky concurrency, workarounds. Applies globally.
121- Feature-specific guidance in each `feature/*/CLAUDE.md`
122 
123## Approach
124 
125- Read existing files before writing. Don't re-read unless changed.
126- Thorough in reasoning, concise in output.
127- Skip files over 100KB unless required.
128- No sycophantic openers or closing fluff.
129- No emojis or em-dashes.
130- Do not guess APIs, versions, flags, commit SHAs, or package names. Verify by reading code or docs before asserting, researching if necessary.
131 

Commands it names

  • ./gradlew :composeApp:assembleDebug
  • ./gradlew :composeApp:run
  • ./gradlew :composeApp:packageExe :composeApp:packageMsi
  • ./gradlew :composeApp:packageDmg :composeApp:packagePkg
  • ./gradlew :composeApp:packageDeb :composeApp:packageRpm
  • ./gradlew build
  • gradle/libs.versions.toml

Sections

  • Komi Store
  • Build
  • Structure
  • Architecture
  • State pattern (every screen)
  • Navigation
  • DI
  • Core repositories (`core/domain`)
  • Tech
  • Convention plugins (`build-logic/convention/`)
  • Adding a feature
  • Key configuration
  • Active skills (apply on matching domain)
  • Conventions
  • Approach

What it covers

buildcode-stylearchitecturegit-pr

Stack — with the evidence

kotlin

(1.00)

java

(0.60)

github-actions

(0.60)

Format

CLAUDE.md

Claude Code's memory file. Shaped like AGENTS.md but with two things it lacks: @path imports, so shared rules live in one place, and a user-scope layer that follows the developer across repos rather than shipping with the code.

What the corpus says about it

Repository

Owner
kurikomi-labs
Language
—
License
—
Archived
no

All configs in this repo

Also in kurikomi-labs/komi-store

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
kurikomi-labs/komi-storefeature/dev-profile/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch40/1003 days ago
kurikomi-labs/komi-storefeature/favourites/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch40/1003 days ago
kurikomi-labs/komi-storefeature/home/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch54/1003 days ago
kurikomi-labs/komi-storefeature/profile/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch54/1003 days ago
kurikomi-labs/komi-storefeature/tweaks/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1archmonorepo54/1003 days ago
kurikomi-labs/komi-storefeature/recently-viewed/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch35/1003 days ago
kurikomi-labs/komi-storefeature/search/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch54/1003 days ago
kurikomi-labs/komi-storefeature/starred/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch54/1003 days ago
kurikomi-labs/komi-storeAGENTS.md · 17kAGENTS.mdkotlinjava+1buildlint-formatstylearch+197/1003 days ago
kurikomi-labs/komi-storefeature/apps/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch58/1003 days ago
kurikomi-labs/komi-storefeature/auth/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1archsecurity58/1003 days ago
kurikomi-labs/komi-storefeature/details/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch53/1003 days ago
Diff against feature/dev-profile/CLAUDE.md Diff against feature/favourites/CLAUDE.md Diff against feature/home/CLAUDE.md Diff against feature/profile/CLAUDE.md Diff against feature/tweaks/CLAUDE.md Diff against feature/recently-viewed/CLAUDE.md Diff against feature/search/CLAUDE.md Diff against feature/starred/CLAUDE.md Diff against AGENTS.md Diff against feature/apps/CLAUDE.md Diff against feature/auth/CLAUDE.md Diff against feature/details/CLAUDE.md

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
Adit-Jain-srm/NightmareNetCLAUDE.md · 45CLAUDE.mdtypescriptpython+18buildtestlint-formatstyle+6100/1003 days ago
nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4kCLAUDE.mdtypescriptnode+16setupbuildstylearch+2100/1003 days ago
stacklok/toolhiveCLAUDE.md · 2.0kCLAUDE.mdgogithub-actionsbuildteststylearch+4100/1003 days ago
dotCMS/corecore-web/CLAUDE.md · 949CLAUDE.mdjavanode+13teststylearchtesting-strategy+3100/1003 days ago
microsoft/playwrightCLAUDE.md · 94kCLAUDE.mdtypescriptjavascript+10buildtestlint-formatstyle+7100/1003 days ago
filamentphp/filamentCLAUDE.md · 32kCLAUDE.mdphplaravel+5buildtestlint-formatstyle+7100/1003 days ago
livewire/livewireCLAUDE.md · 24kCLAUDE.mdphpvitest+4setupbuildteststyle+4100/1003 days ago
bagisto/bagistoCLAUDE.md · 28kCLAUDE.mdphplaravel+8setupbuildteststyle+5100/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack