mirror of
https://github.com/vide/matedroid.git
synced 2026-01-20 00:03:17 +08:00
feat: add Claude Code skills for common tasks
- check-api: Query Teslamate API to inspect JSON response format - release: Bump version, update changelog, tag and push - translate: Add strings to all 4 locale files - new-screen: Scaffold a new Compose screen Also adds .env.example for API URL configuration and fixes .gitignore to allow .claude/skills/release/ directory. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: check-api
|
||||
description: Check Teslamate API response format for a given endpoint. Use when you need to understand the JSON structure returned by the API.
|
||||
allowed-tools: Read, WebFetch
|
||||
---
|
||||
|
||||
# Check Teslamate API
|
||||
|
||||
Query the Teslamate API to inspect JSON response format for endpoints.
|
||||
|
||||
## Configuration
|
||||
|
||||
The API URL should be set in a `.env` file at the project root (gitignored):
|
||||
|
||||
```
|
||||
TESLAMATE_API_URL=https://your-teslamate-api.example.com
|
||||
```
|
||||
|
||||
If no `.env` file exists, ask the user for their Teslamate API URL.
|
||||
|
||||
## Common Endpoints
|
||||
|
||||
- `/api/v1/cars` - List all cars
|
||||
- `/api/v1/cars/{id}` - Car details with current state (battery, location, climate, etc.)
|
||||
- `/api/v1/cars/{id}/drives` - Drive history (supports `?start_date=` and `?end_date=`)
|
||||
- `/api/v1/cars/{id}/charges` - Charge history (supports `?start_date=` and `?end_date=`)
|
||||
- `/api/v1/cars/{id}/drives/{drive_id}` - Single drive details with positions
|
||||
- `/api/v1/cars/{id}/charges/{charge_id}` - Single charge details with charging curve
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Read the `.env` file to get `TESLAMATE_API_URL`
|
||||
2. If not found, ask the user for the URL
|
||||
3. Use WebFetch to query the requested endpoint
|
||||
4. Present the JSON structure clearly, highlighting relevant fields
|
||||
|
||||
## Date Format
|
||||
|
||||
The API's parseDateParam function only accepts:
|
||||
- RFC3339 format: `2024-12-07T00:00:00Z`
|
||||
- DateTime format: `2024-12-07 00:00:00`
|
||||
@@ -0,0 +1,131 @@
|
||||
---
|
||||
name: new-screen
|
||||
description: Scaffold a new Jetpack Compose screen following project patterns. Use when creating a new screen or view in the app.
|
||||
allowed-tools: Read, Write, Edit, Glob
|
||||
---
|
||||
|
||||
# New Screen Skill
|
||||
|
||||
Create a new Jetpack Compose screen following MateDroid's patterns.
|
||||
|
||||
## Project Structure
|
||||
|
||||
Screens are located in `app/src/main/java/com/matedroid/ui/screens/`:
|
||||
```
|
||||
screens/
|
||||
├── dashboard/
|
||||
│ └── DashboardScreen.kt
|
||||
├── drives/
|
||||
│ ├── DrivesScreen.kt
|
||||
│ └── DriveDetailScreen.kt
|
||||
├── charges/
|
||||
│ ├── ChargesScreen.kt
|
||||
│ └── ChargeDetailScreen.kt
|
||||
├── settings/
|
||||
│ └── SettingsScreen.kt
|
||||
└── {feature}/
|
||||
└── {Feature}Screen.kt
|
||||
```
|
||||
|
||||
## Process
|
||||
|
||||
1. Ask the user for:
|
||||
- Screen name (e.g., "Battery Health")
|
||||
- Brief description of what it displays
|
||||
- Whether it needs navigation parameters
|
||||
|
||||
2. Read an existing screen as reference (e.g., `DashboardScreen.kt`)
|
||||
|
||||
3. Create the new screen file following the pattern
|
||||
|
||||
## Screen Template
|
||||
|
||||
```kotlin
|
||||
package com.matedroid.ui.screens.{feature}
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matedroid.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun {Feature}Screen(
|
||||
onNavigateBack: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.{feature}_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
// Screen content here
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## After Creating the Screen
|
||||
|
||||
1. Add string resources for the screen title using the translate skill
|
||||
2. Add navigation route to the app's navigation graph
|
||||
3. Remind the user to wire up the navigation
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Loading State
|
||||
```kotlin
|
||||
var isLoading by remember { mutableStateOf(true) }
|
||||
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator()
|
||||
} else {
|
||||
// Content
|
||||
}
|
||||
```
|
||||
|
||||
### API Data Fetching
|
||||
```kotlin
|
||||
LaunchedEffect(Unit) {
|
||||
// Fetch data from TeslamateApiService
|
||||
}
|
||||
```
|
||||
|
||||
### Pull to Refresh
|
||||
```kotlin
|
||||
val pullRefreshState = rememberPullToRefreshState()
|
||||
PullToRefreshBox(state = pullRefreshState, isRefreshing = isRefreshing) {
|
||||
// Content
|
||||
}
|
||||
```
|
||||
|
||||
### Cards
|
||||
```kotlin
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant
|
||||
)
|
||||
) {
|
||||
// Card content
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: release
|
||||
description: Create a new release. Bumps version, updates changelog, creates fastlane changelog, commits, tags, and pushes.
|
||||
allowed-tools: Read, Edit, Write, Bash, Glob
|
||||
---
|
||||
|
||||
# Release Skill
|
||||
|
||||
Create a new release for MateDroid.
|
||||
|
||||
## Pre-flight Checks
|
||||
|
||||
1. Ensure you're on the `main` branch with no uncommitted changes
|
||||
2. Verify the `[Unreleased]` section in `CHANGELOG.md` has content to release
|
||||
|
||||
## Release Process
|
||||
|
||||
### 1. Determine Version
|
||||
|
||||
Ask the user what type of release:
|
||||
- **patch** (0.10.0 → 0.10.1): Bug fixes only
|
||||
- **minor** (0.10.0 → 0.11.0): New features, backwards compatible
|
||||
- **major** (0.10.0 → 1.0.0): Breaking changes (requires explicit user confirmation)
|
||||
|
||||
### 2. Update Version in build.gradle.kts
|
||||
|
||||
Edit `app/build.gradle.kts`:
|
||||
- Increment `versionCode` by 1
|
||||
- Update `versionName` to the new version
|
||||
|
||||
### 3. Update CHANGELOG.md
|
||||
|
||||
1. Change `## [Unreleased]` to `## [X.Y.Z] - YYYY-MM-DD` (today's date)
|
||||
2. Add a new empty `## [Unreleased]` section above it
|
||||
3. Add the new version link at the bottom:
|
||||
```
|
||||
[X.Y.Z]: https://github.com/vide/matedroid/compare/vPREVIOUS...vX.Y.Z
|
||||
```
|
||||
4. Update the `[Unreleased]` link to compare from the new version
|
||||
|
||||
### 4. Create Fastlane Changelog
|
||||
|
||||
Create `fastlane/metadata/android/en-US/changelogs/{versionCode}.txt` with the release notes.
|
||||
|
||||
Format (max 500 chars for Play Store):
|
||||
```
|
||||
Added:
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
|
||||
Changed:
|
||||
- Change 1
|
||||
|
||||
Fixed:
|
||||
- Fix 1
|
||||
```
|
||||
|
||||
Keep it concise - this appears in Play Store and F-Droid.
|
||||
|
||||
### 5. Commit and Tag
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "chore: release vX.Y.Z"
|
||||
git tag -a vX.Y.Z -m "Release X.Y.Z"
|
||||
```
|
||||
|
||||
### 6. Push
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
git push origin vX.Y.Z
|
||||
```
|
||||
|
||||
### 7. Create GitHub Release
|
||||
|
||||
Use `gh release create vX.Y.Z --title "vX.Y.Z" --notes-file -` with the changelog content.
|
||||
|
||||
The GitHub Actions workflow will automatically:
|
||||
- Build APK and AAB
|
||||
- Upload to GitHub release
|
||||
- Deploy to Google Play (alpha track)
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
name: translate
|
||||
description: Add a new translatable string to all locale files (English, Italian, Spanish, Catalan). Use when adding user-visible text to the app.
|
||||
allowed-tools: Read, Edit
|
||||
---
|
||||
|
||||
# Translate Skill
|
||||
|
||||
Add a new string resource to all 4 locale files.
|
||||
|
||||
## String Resource Files
|
||||
|
||||
| Locale | File |
|
||||
|---------|-----------------------------------------------|
|
||||
| English | `app/src/main/res/values/strings.xml` |
|
||||
| Italian | `app/src/main/res/values-it/strings.xml` |
|
||||
| Spanish | `app/src/main/res/values-es/strings.xml` |
|
||||
| Catalan | `app/src/main/res/values-ca/strings.xml` |
|
||||
|
||||
## Process
|
||||
|
||||
1. Ask the user for:
|
||||
- The string name (use `snake_case`, e.g., `drive_details_title`)
|
||||
- The English text
|
||||
- Context for translators (optional but recommended)
|
||||
|
||||
2. Generate translations for Italian, Spanish, and Catalan
|
||||
|
||||
3. Add to all 4 files with an XML comment for context:
|
||||
```xml
|
||||
<!-- Context: Shown as the title of the drive details screen -->
|
||||
<string name="drive_details_title">Drive Details</string>
|
||||
```
|
||||
|
||||
## Guidelines
|
||||
|
||||
- Use `snake_case` for string names (e.g., `settings_title`, `drive_history`)
|
||||
- Add XML comments above strings to provide context for translators
|
||||
- Technical terms like AC, DC, kW, kWh should NOT be translated
|
||||
- Format specifiers (`%s`, `%d`, `%1$s`) must be preserved in translations
|
||||
- Keep translations natural - don't be overly literal
|
||||
|
||||
## String with Parameters
|
||||
|
||||
For strings with parameters, use positional format specifiers:
|
||||
```xml
|
||||
<string name="distance_km">%1$d km away</string>
|
||||
```
|
||||
|
||||
In Kotlin:
|
||||
```kotlin
|
||||
stringResource(R.string.distance_km, distance)
|
||||
```
|
||||
|
||||
## Plurals
|
||||
|
||||
For quantity strings, use plurals:
|
||||
```xml
|
||||
<plurals name="days_count">
|
||||
<item quantity="one">%d day</item>
|
||||
<item quantity="other">%d days</item>
|
||||
</plurals>
|
||||
```
|
||||
|
||||
## After Adding Strings
|
||||
|
||||
Remind the user to use `stringResource(R.string.xxx)` in Compose code:
|
||||
```kotlin
|
||||
Text(stringResource(R.string.drive_details_title))
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
# Copy this file to .env and fill in your values
|
||||
# Used by Claude Code skills (check-api)
|
||||
|
||||
# Your Teslamate API URL (e.g., https://teslamate-api.example.com)
|
||||
TESLAMATE_API_URL=
|
||||
+4
-1
@@ -17,7 +17,7 @@
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
release/
|
||||
/release/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
@@ -95,3 +95,6 @@ mockups/
|
||||
|
||||
# Logo source files (generated icons are in res/mipmap-*)
|
||||
matedroid-logo*.png
|
||||
|
||||
# Local environment configuration
|
||||
.env
|
||||
|
||||
Reference in New Issue
Block a user