mobile-offline-support — скилл для Claude Code: офлайн-режим
Скилл для офлайн-первого подхода в мобильных приложениях: локальное хранилище, очередь синхронизации, разрешение конфликтов.
npx skills add secondsky/claude-skills --skill mobile-offline-support -a claude-codeЧто делает mobile-offline-support
Скилл задаёт агенту схему работы с данными, когда сеть пропадает. Внутри — класс OfflineManager на React Native: чтение из AsyncStorage, запись, постановка изменений в очередь и отправка на сервер, когда соединение вернулось. Состояние сети отслеживает NetInfo.
Очередь ограничена константой MAX_SYNC_QUEUE_LENGTH со значением 1000: при переполнении самые старые элементы отбрасываются с предупреждением в консоль. Конфликты решаются функцией resolveConflict по принципу last-write-wins, есть закомментированный вариант слияния полей. Для интерфейса приложен компонент OfflineIndicator — баннер, который показывается, пока связи нет.
Методы fetchFromServer и syncToServer помечены TODO: это примеры, а не готовый клиент. Подставьте свои эндпоинты и API_BASE_URL, иначе запросы уйдут в никуда. В references/native-implementations.md лежат варианты для iOS Core Data и Android Room с WorkManager.
Какие задачи решает
- сохранить данные формы, пока связи нет
- отправить накопленные изменения после возврата в сеть
- разрешить конфликт между локальной и серверной версией записи
- показать пользователю, что приложение работает офлайн
- ограничить рост очереди синхронизации
Примеры запросов агенту
- Добавь офлайн-режим в экран заказа: локальное хранилище и очередь синхронизации
- Почему конфликты синхронизации перезаписывают свежие данные? Разбери resolveConflict
- Сделай баннер офлайн-режима через OfflineIndicator
Как установить mobile-offline-support
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill mobile-offline-support -a claude-code2Вручную: положить файлы
~/.claude/skills/mobile-offline-support/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/mobile-offline-support/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill mobile-offline-support -a codex2Вручную: положить файлы
.agents/skills/mobile-offline-support/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill mobile-offline-support -a cursor2Вручную: положить файлы
.cursor/skills/mobile-offline-support/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install secondsky/claude-skills mobile-offline-support2Вручную: положить файлы
.github/skills/mobile-offline-support/SKILL.md1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill mobile-offline-support -a gemini-cli2Командой платформы
gemini skills install https://github.com/secondsky/claude-skills --path plugins/mobile-offline-support/skills/mobile-offline-supportВручную: положить файлы
.devin/skills/mobile-offline-support/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill mobile-offline-support -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора89
Похожие
Рядом в теме «Мобильная разработка»
Всё по теме «Мобильная разработка» →Вопросы о mobile-offline-support
Как установить mobile-offline-support в Claude?
Выполните npx skills add secondsky/claude-skills --skill mobile-offline-support -a claude-code. Скилл окажется в ~/.claude/skills/mobile-offline-support/SKILL.md.
Что делает mobile-offline-support?
Даёт агенту шаблоны для офлайн-первых мобильных приложений: кеш в локальном хранилище, очередь отложенной синхронизации, разрешение конфликтов и индикатор отсутствия сети.
На чём сломается этот скилл?
Методы fetchFromServer и syncToServer — заглушки с TODO. Без своих эндпоинтов и API_BASE_URL синхронизация не заработает.
Исходный текст
SKILL.md · MIT
---
name: mobile-offline-support
description: Offline-first mobile apps with local storage, sync queues, conflict resolution. Use for offline functionality, data sync, connectivity handling, or encountering sync conflicts, queue management, storage limits, network transition errors.
license: MIT
---
# Mobile Offline Support
Build offline-first mobile applications with local storage and synchronization.
## React Native Implementation
```javascript
import AsyncStorage from '@react-native-async-storage/async-storage';
import NetInfo from '@react-native-community/netinfo';
class OfflineManager {
constructor() {
this.syncQueue = [];
this.isOnline = true;
// Maximum items in sync queue before discarding oldest
this.MAX_SYNC_QUEUE_LENGTH = 1000;
NetInfo.addEventListener(state => {
this.isOnline = state.isConnected;
if (this.isOnline) this.processQueue();
});
}
/**
* Fetch data from server.
* TODO: Replace with actual API endpoint implementation.
*/
async fetchFromServer(key) {
try {
// Example implementation - replace with your API
const response = await fetch(`${API_BASE_URL}/data/${key}`);
if (!response.ok) {
throw new Error(`Server returned ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('fetchFromServer failed:', error);
throw new Error(`Failed to fetch ${key}: ${error.message}`);
}
}
/**
* Sync data to server.
* TODO: Replace with actual API endpoint implementation.
*/
async syncToServer(key, data) {
try {
// Example implementation - replace with your API
const response = await fetch(`${API_BASE_URL}/data/${key}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`Server returned ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('syncToServer failed:', error);
throw new Error(`Failed to sync ${key}: ${error.message}`);
}
}
async getData(key) {
const cached = await AsyncStorage.getItem(key);
if (cached) return JSON.parse(cached);
if (this.isOnline) {
const data = await this.fetchFromServer(key);
await AsyncStorage.setItem(key, JSON.stringify(data));
return data;
}
return null;
}
async saveData(key, data) {
await AsyncStorage.setItem(key, JSON.stringify(data));
if (this.isOnline) {
await this.syncToServer(key, data);
} else {
// Add to queue
this.syncQueue.push({ key, data, timestamp: Date.now() });
// Enforce queue bounds - discard oldest if exceeded
while (this.syncQueue.length > this.MAX_SYNC_QUEUE_LENGTH) {
const discarded = this.syncQueue.shift();
console.warn(`Sync queue full - discarded oldest item: ${discarded.key}`);
}
// Persist trimmed queue
await AsyncStorage.setItem('syncQueue', JSON.stringify(this.syncQueue));
}
}
async processQueue() {
const failedItems = [];
for (const item of this.syncQueue) {
try {
await this.syncToServer(item.key, item.data);
} catch (err) {
console.error('Sync failed:', err);
failedItems.push(item);
}
}
this.syncQueue = failedItems;
if (failedItems.length === 0) {
await AsyncStorage.removeItem('syncQueue');
} else {
await AsyncStorage.setItem('syncQueue', JSON.stringify(failedItems));
}
}
}
```
## Conflict Resolution
```javascript
function resolveConflict(local, server) {
// Last-write-wins
if (local.updatedAt > server.updatedAt) return local;
return server;
// Or merge changes
// return { ...server, ...local };
}
```
## UI Indicators
```jsx
function OfflineIndicator() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
return NetInfo.addEventListener(state => {
setIsOnline(state.isConnected);
});
}, []);
if (isOnline) return null;
return (
<View style={styles.banner}>
<Text>You're offline. Changes will sync when connected.</Text>
</View>
);
}
```
## Best Practices
- Cache frequently accessed data locally
- Queue actions for later sync
- Show clear offline indicators
- Handle sync conflicts gracefully
- Compress stored data
- Test offline scenarios thoroughly
## Native Implementations
See [references/native-implementations.md](references/native-implementations.md) for:
- iOS Core Data with sync manager
- Android Room database with WorkManager sync
## Avoid
- Assuming connectivity
- Losing data on sync failures
- Unbounded queue growth
- Syncing sensitive data insecurely
© secondsky · MIT · secondsky/claude-skills