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

feature/auth/CLAUDE.md
CLAUDE.md

Quality

58/100

Scores the file, not the repository.

Length

585 words

8 headings · 2 code blocks

Repository

17k

— · pushed 5 days ago

Last changed

3 days ago

First indexed 3 days ago.
kurikomi-labs/komi-store/feature/auth/CLAUDE.mdRawGitHub
1# Auth Feature
2 
3Three GitHub sign-in paths, picked per session: **web OAuth + PKCE + handoff** (primary), **device flow** (fallback), **Personal Access Token paste** (last resort). Works on Android + Desktop.
4 
5## Structure
6 
7```
8feature/auth/
9├── domain/repository/AuthenticationRepository.kt # contract + AuthPath, DeviceFlowStart, PollOutcome, WebAuthRegistration, PatRejectedException
10├── data/
11│ ├── crypto/PkceGenerator.kt # SHA-256 PKCE triplet (state + verifier + challenge)
12│ ├── network/GitHubAuthApi.kt # direct + backend-proxied device-flow endpoints
13│ ├── network/WebAuthApi.kt # web-OAuth register + handoff consume
14│ ├── repository/AuthenticationRepositoryImpl.kt
15│ └── di
16└── presentation/
17 ├── AuthenticationViewModel / State / Action / Event / Root
18 ├── AuthDeepLinkBus.kt # SharedFlow bridge from app-level deep-link parser to VM
19 └── components/
20```
21 
22## Key interface
23 
24```kotlin
25interface AuthenticationRepository {
26 val accessTokenFlow: Flow<String?>
27 
28 suspend fun startDeviceFlow(): DeviceFlowStart
29 suspend fun awaitDeviceToken(start: GithubDeviceStart): GithubDeviceTokenSuccess
30 suspend fun pollDeviceTokenOnce(deviceCode: String, path: AuthPath): PollOutcome
31 
32 suspend fun signInWithPat(token: String): Result<Unit>
33 
34 suspend fun registerWebAuth(): Result<WebAuthRegistration>
35 suspend fun exchangeWebAuthHandoff(handoffId: String): Result<String>
36}
37 
38enum class AuthPath { Backend, Direct }
39```
40 
41## Navigation
42 
43`GithubStoreGraph.AuthenticationScreen`.
44 
45## Web OAuth path (primary)
46 
471. `PkceGenerator.generate()` → `(state, codeVerifier, codeChallenge)` (S256).
482. `WebAuthApi.register(state, codeChallenge, codeVerifier)` → POST `https://github-store.org/auth/register`. Cloudflare Worker stores `(state → {codeVerifier, codeChallenge})` in Workers KV with short TTL and returns `auth_url` (the `github.com/login/oauth/authorize?…` URL).
493. VM opens `auth_url` in user's browser via `BrowserHelper`.
504. User authorizes on GitHub. GitHub redirects to `https://github-store.org/auth/callback?code=…&state=…`.
515. Worker re-validates `state`, exchanges `code` against `api.github-store.org` (backend posts to GitHub `/oauth/access_token` with the stored verifier), backend writes `(handoffId → access_token)` to Postgres with 60s TTL.
526. Worker redirects browser to `githubstore://auth?h=<handoffId>` (custom scheme picked up by app via OS deep link).
537. App-level `DeepLinkParser` routes the URI through `AuthDeepLinkBus`. VM calls `exchangeWebAuthHandoff(handoffId)` → `WebAuthApi.consumeHandoff` → POST `api.github-store.org/v1/oauth/handoff/<id>` (atomic `DELETE…RETURNING` — single-use). Token lands in `TokenStore`.
54 
55Custom scheme is public — any app can fire `githubstore://auth?…`. The `state` parameter and 60s server-side TTL are the integrity guards; without a live KV entry the handoff is a no-op.
56 
57## Device flow path (fallback)
58 
59Used when web flow can't complete (browser unreachable, deep link not registered, user explicitly picks "Use device code instead").
60 
61- Primary sub-path: backend proxy `/v1/auth/device/start` + `/poll` on `api.github-store.org` for networks throttling `github.com` (China, corporate filters).
62- Each session picks one `AuthPath` (`Backend` | `Direct`), persists in `SavedStateHandle`. Only escalates `Backend → Direct` on infra errors (timeout / 5xx / 429-without-Retry-After). HTTP 4xx and GitHub negative 200-bodies (`authorization_pending`, `slow_down`, `access_denied`, `expired_token`, `bad_verification_code`) are real answers — never trigger fallback.
63- Backend rate limits hard: 10 starts/hr, 200 polls/hr per IP. Don't add retry loops on top of Ktor's `HttpRequestRetry(maxRetries = 2)`.
64- Backend responses carry `X-Request-ID` — `GitHubAuthApi` embeds it in error messages via `asRequestIdTag()` for cross-log correlation.
65 
66## PAT path (last resort)
67 
68`signInWithPat(token)`:
691. Client-side format check (rejects obvious paste-errors — needs `ghp_` / `github_pat_` prefix).
702. Network check against GitHub `/user`. 401 → `PatRejectedException(BadCredentials)`, 403 → `InsufficientScope`, other non-2xx → `Other(statusCode)`. On reject the sheet stays open.
713. If GitHub is unreachable (timeout/DNS/block) the token persists optimistically — the whole reason this path exists is for users who can't reach GitHub reliably. A bad-but-unreachable token surfaces a 401 on the first authenticated call.
72 
73## Notes
74 
75- Token stored via `TokenStore` (DataStore-backed). `accessTokenFlow` observed app-wide.
76- `GITHUB_CLIENT_ID` in `local.properties` for builds — must match the OAuth App registered on the backend and used by the Worker.
77- Endpoints: `WEB_ORIGIN = https://github-store.org`, `BACKEND_ORIGIN = https://api.github-store.org`. Constants in `core/data/network/BackendEndpoints.kt`.
78- Android deep-link filters in `composeApp/src/androidMain/AndroidManifest.xml`: scheme `githubstore`, hosts `auth`, `callback`, `repo`, `apps`. Desktop registers the protocol via `DesktopDeepLink` on Win/Linux (macOS uses the bundle Info.plist `CFBundleURLTypes`).
79 

Sections

  • Auth Feature
  • Structure
  • Key interface
  • Navigation
  • Web OAuth path (primary)
  • Device flow path (fallback)
  • PAT path (last resort)
  • Notes

What it covers

architecturesecurity

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-storeCLAUDE.md · 17kCLAUDE.mdkotlinjava+1buildstylearchgit78/1003 days ago
kurikomi-labs/komi-storefeature/apps/CLAUDE.md · 17kCLAUDE.mdkotlinjava+1arch58/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 CLAUDE.md Diff against feature/apps/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
livewire/livewireCLAUDE.md · 24kCLAUDE.mdphpvitest+4setupbuildteststyle+4100/1003 days ago
filamentphp/filamentCLAUDE.md · 32kCLAUDE.mdphplaravel+5buildtestlint-formatstyle+7100/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
Adit-Jain-srm/NightmareNetCLAUDE.md · 45CLAUDE.mdtypescriptpython+18buildtestlint-formatstyle+6100/1003 days ago
microsoft/playwrightCLAUDE.md · 94kCLAUDE.mdtypescriptjavascript+10buildtestlint-formatstyle+7100/1003 days ago
nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4kCLAUDE.mdtypescriptnode+16setupbuildstylearch+2100/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