Skip to content
Agentmart
Submit a tool

add-permission

Request a runtime permission (notifications, camera, gallery out of the box; location, microphone or any other after adding its Calf module) via the app-level…

Skill by KotlinFoundation

IndexedMIT★ 28
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/kotlinfoundation-add-permission

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Request a runtime permission (notifications, camera, gallery out of the box; location, microphone or any other after adding its Calf module) via the app-level AppPermissionState API. Use when a screen needs to ask the user for a device permission. For full push/FCM setup (not just the notification permission prompt), use enable-notifications instead.

Use cases: backend, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/add-permission

What's inside

Skill name
add-permission
Description
Request a runtime permission (notifications, camera, gallery out of the box; location, microphone or any other after adding its Calf module) via the app-level AppPermissionState API. Use when a screen needs to ask the user for a device permission. For full push/FCM setup (not just the notification permission prompt), use enable-notifications instead.
License
MIT
Instructions
74 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Add a runtime permission

Permissions go through the app-level `AppPermissionState` wrapper (backed by Calf) — real dialogs on
Android/iOS, granted no-op on desktop/web. **Never use Calf types directly in screens.**

Helpers live in `shared/src/commonMain/kotlin/com/kotlinfoundation/koko/util/permissions/AppPermissionState.kt`.

## Ready-made helpers

| Helper | iOS `Info.plist` key |
|---|---|
| `rememberNotificationPermissionState()` | — |
| `rememberCameraPermissionState()` | `NSCameraUsageDescription` |
| `rememberGalleryPermissionState()` | `NSPhotoLibraryUsageDescription` |

Those three are the permissions the kit ships. **Any other permission needs its Calf module added
first** — the kit deliberately does not depend on the umbrella `calf-permissions` artifact:

```kotlin
// MobileApp/gradle/libs.versions.toml
calf-permissions-location = { module = "com.mohamedrejeb.calf:calf-permissions-location", version.ref = "calf" }

// MobileApp/shared/build.gradle.kts, commonMain
implementation(libs.calf.permissions.location)
```

Then call the generic helper and add the iOS key:

```kotlin
rememberAppPermissionState(Permission.FineLocation)   // + NSLocationWhenInUseUsageDescription
```

> **Never switch to the umbrella `calf-permissions` module.** It links every permission API, so
> App Store review rejects the build with **ITMS-90683** demanding a purpose string for location,
> bluetooth, contacts and the rest — permissions the app never uses. One module per permission you
> actually request.

## Use it in a screen

Each helper returns `AppPermissionState { isGranted, shouldShowRationale, request(), openSettings() }`:

```kotlin
@Composable
fun CameraScreen() {
    val camera = rememberCameraPermissionState { granted -> /* result after request() */ }
    when {
        camera.isGranted -> CameraPreview()
        camera.shouldShowRationale -> RationaleCard(onAllow = { camera.openSettings() })
        else -> Button(onClick = { camera.request() }) { Text("Enable camera") }
    }
}
```

## Ask on screen entry

For permissions best requested as the screen appears (e.g. notifications on Home):

```kotlin
RequestPermissionOnEntry(rememberNotificationPermissionState())
```
It skips if already granted, or if the user previously denied (never re-prompt unasked — show a
rationale UI instead).

## iOS / Android setup

- **iOS**: add the matching `NS*UsageDescription` key to `iosApp/iosApp/Info.plist`. Camera/gallery/
  location/microphone all require one — a **missing key hard-crashes** the app when the permission opens.
  Notifications need none.
- **Android**: add the `<uses-permission>` entry to `androidApp/src/main/AndroidManifest.xml` if the
  permission requires one.

Validate with the `run-quality-gates` skill.

From KotlinFoundation/kmp-contest-starter-kit, MIT.

More from KotlinFoundation/kmp-contest-starter-kit

Signals

Stars
28
Forks
13
Open issues
1
Last commit (this folder)
Aug 17, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from KotlinFoundation

Cite this page

add-permission skill. Agent Mart. https://agentmart.dev/skills/kotlinfoundation-add-permission (last updated 2026-10-24)