Compare commits
3 Commits
1bfef33da1
...
57857cda4d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57857cda4d | ||
|
|
0c5057bc21 | ||
|
|
c379ee8efc |
@@ -17,7 +17,6 @@ home-configs/
|
||||
├── GLOBAL_RULES.md # глобальные правила для всех агентов
|
||||
├── claude/
|
||||
│ ├── hooks/ # хуки аккаунтов Claude Code
|
||||
│ ├── skills/ # кастомные скиллы для Claude Code (и Gemini)
|
||||
│ └── statusline-command.sh # статусная строка Claude Code
|
||||
└── network/
|
||||
└── README.md # подробная документация по сетевой настройке
|
||||
@@ -164,7 +163,6 @@ bash tests/test_network.sh # полные тесты
|
||||
|
||||
Также устанавливается:
|
||||
- `~/.config/ai-setup/global_rules.md` и native rule-файлы (`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, `~/.kimi-code/AGENTS.md`, `~/.gemini/GEMINI.md`)
|
||||
- Скиллы из `home-configs/claude/skills/` в `~/.claude/skills/` и `~/.gemini/config/plugins/local-setup/skills/`
|
||||
|
||||
## Android CLI
|
||||
|
||||
|
||||
60
home-configs/claude/hooks/logout-account-hook.sh
Executable file
60
home-configs/claude/hooks/logout-account-hook.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2026 Виталий Никитенко. MIT License.
|
||||
# UserPromptSubmit hook: перехватывает /logout, /logout-glm, /logout-deepseek, /logout-kimi.
|
||||
# Удаляет сохранённый API-ключ провайдера, чтобы при следующем запуске лаунчер
|
||||
# запросил новый.
|
||||
# /logout-glm | /logout-deepseek | /logout-kimi — явно указанный провайдер.
|
||||
# /logout (без суффикса) — провайдер по AI_LAUNCHER (glm/deepseek/kimi).
|
||||
# Для ai-claude и прочих лаунчеров /logout отступает (exit 0) — пусть работает
|
||||
# нативный oauth-logout. exit 2 после удаления: LLM не нужна, и нативная
|
||||
# /logout не пытается сделать бессмысленный oauth-logout для api-key провайдеров.
|
||||
|
||||
input=$(cat)
|
||||
prompt=$(echo "$input" | jq -r '.user_prompt // .prompt // empty' 2>/dev/null)
|
||||
normalized=$(echo "$prompt" | sed 's|^[[:space:]]*/||; s|[[:space:]]*$||')
|
||||
cmd=$(echo "$normalized" | awk '{print $1}')
|
||||
|
||||
target=""
|
||||
case "$cmd" in
|
||||
logout-glm) target=glm ;;
|
||||
logout-deepseek) target=deepseek ;;
|
||||
logout-kimi) target=kimi ;;
|
||||
logout)
|
||||
case "${AI_LAUNCHER:-claude}" in
|
||||
glm|deepseek|kimi) target="$AI_LAUNCHER" ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
|
||||
CFG="$HOME/.config/ai-setup"
|
||||
|
||||
case "$target" in
|
||||
glm)
|
||||
rm -f "$CFG/glm_key"
|
||||
echo "✓ GLM ключ удалён. Перезапусти ai-glm, чтобы ввести новый." >&2
|
||||
;;
|
||||
deepseek)
|
||||
rm -f "$CFG/deepseek_key"
|
||||
echo "✓ DeepSeek ключ удалён. Перезапусти ai-deepseek, чтобы ввести новый." >&2
|
||||
;;
|
||||
kimi)
|
||||
KEYS_DIR="$CFG/kimi_keys"
|
||||
current=$(cat "$KEYS_DIR/current" 2>/dev/null || true)
|
||||
if [ -n "$current" ]; then
|
||||
rm -f "$KEYS_DIR/${current}.key" "$KEYS_DIR/${current}.meta"
|
||||
fi
|
||||
# Пересчёт current: переключаемся на первый оставшийся ключ либо сбрасываем.
|
||||
mapfile -t keys < <(ls "$KEYS_DIR"/*.key 2>/dev/null | xargs -I{} basename {} .key | sort)
|
||||
if [ "${#keys[@]}" -gt 0 ]; then
|
||||
echo "${keys[0]}" > "$KEYS_DIR/current"
|
||||
echo "✓ Kimi ключ (${current:-нет}) удалён. Активен: ${keys[0]}. Перезапусти ai-kimi." >&2
|
||||
else
|
||||
rm -f "$KEYS_DIR/current"
|
||||
echo "✓ Kimi ключ (${current:-нет}) удалён. Других ключей нет. Перезапусти ai-kimi." >&2
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 2
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
name: add-account
|
||||
description: Add a new account or API key (handled by UserPromptSubmit hook, no LLM needed)
|
||||
---
|
||||
|
||||
Хук уже обработал запрос. Ответь ТОЛЬКО этим текстом (без markdown, без лишних слов):
|
||||
|
||||
Для Claude.ai: браузер открыт — авторизуйся там. После авторизации новый аккаунт сохранится автоматически и сразу станет активным (Claude Code на Linux перечитывает токен на лету).
|
||||
|
||||
Для Kimi: укажи API-ключ в том же сообщении: `/add-account sk-...`. Хук проверит и сохранит ключ; ai-kimi перезапустится с ним.
|
||||
|
||||
/switch-account переключает между всеми сохранёнными аккаунтами/ключами по кругу.
|
||||
@@ -1,87 +0,0 @@
|
||||
---
|
||||
name: android-cli
|
||||
description: Google Android CLI - официальный терминальный инструмент для Android-разработки, SDK, эмуляторов и проектов
|
||||
---
|
||||
|
||||
# Android CLI
|
||||
|
||||
## Назначение
|
||||
|
||||
Google Android CLI (preview) - официальный инструмент от Google для Android-разработки через терминал. Он создан специально для AI-агентов, CI/CD и автоматизации. Позволяет управлять SDK, создавать проекты, запускать эмуляторы и собирать APK без необходимости вручную разбираться с `sdkmanager`, `adb` и Gradle.
|
||||
|
||||
## Установка и обновление
|
||||
|
||||
```bash
|
||||
# Установка (выполняется ai-setup.sh)
|
||||
curl -fsSL https://dl.google.com/android/cli/latest/linux_x86_64/install.sh | bash
|
||||
|
||||
# Обновление
|
||||
android update
|
||||
```
|
||||
|
||||
## Ключевые команды
|
||||
|
||||
| Команда | Назначение |
|
||||
|---------|------------|
|
||||
| `android --version` | Версия Android CLI |
|
||||
| `android info` | Информация об SDK, путях, эмуляторах |
|
||||
| `android sdk list` | Список доступных SDK-пакетов |
|
||||
| `android sdk install <package>` | Установить пакет SDK |
|
||||
| `android create --name="App" --output=./app` | Создать новый Android-проект |
|
||||
| `android emulator create` | Создать виртуальное устройство |
|
||||
| `android emulator start` | Запустить эмулятор |
|
||||
| `android run --apks <path>` | Установить и запустить APK на устройстве/эмуляторе |
|
||||
| `android init` | Развернуть skills для AI-агентов в `~/.claude/skills/` |
|
||||
| `android update` | Обновить сам Android CLI |
|
||||
|
||||
## Workflow с Claude Code
|
||||
|
||||
1. **Проверь окружение**:
|
||||
```bash
|
||||
android info
|
||||
```
|
||||
|
||||
2. **Установи нужные SDK-компоненты**:
|
||||
```bash
|
||||
android sdk install platforms/android-35 build-tools/35.0.0
|
||||
```
|
||||
|
||||
3. **Создай проект** (если нужен новый):
|
||||
```bash
|
||||
android create --name="MyApp" --output=./myapp
|
||||
```
|
||||
|
||||
4. **Собери проект**:
|
||||
```bash
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
|
||||
5. **Запусти на эмуляторе или устройстве**:
|
||||
```bash
|
||||
android emulator start
|
||||
android run --apks app/build/outputs/apk/debug/app-debug.apk
|
||||
```
|
||||
|
||||
## Когда использовать Android CLI
|
||||
|
||||
- Для управления SDK и установки build-tools/platforms без Android Studio.
|
||||
- Для создания новых Android-проектов из терминала.
|
||||
- Для запуска эмулятора и установки APK одной командой.
|
||||
- Для работы в CI/CD или внутри AI-агентов.
|
||||
|
||||
## Когда НЕ нужен Android CLI
|
||||
|
||||
- Для визуального редактирования UI/Layout - используй Android Studio.
|
||||
- Для отладки с breakpoints, Layout Inspector, Compose Preview - используй Android Studio.
|
||||
- Для сложного рефакторинга больших проектов - используй Claude Code в паре с Android Studio.
|
||||
|
||||
## Ограничения
|
||||
|
||||
- **Preview-версия**: API и команды могут меняться. Обновляй через `android update`.
|
||||
- **Windows**: `android emulator` отключён в v0.7.
|
||||
- **Существующий SDK**: если уже установлен Android Studio или `sdkmanager`, Android CLI может использовать тот же SDK или создать новый в `~/.android/sdk`. Проверяй активный путь через `android info`.
|
||||
|
||||
## Полезные ссылки
|
||||
|
||||
- Официальная документация: https://d.android.com/tools/agents
|
||||
- Android CLI skills: https://github.com/android/skills
|
||||
@@ -1,62 +0,0 @@
|
||||
---
|
||||
name: el-review-heavy
|
||||
description: Use when пользователь запрашивает тяжелое code-review между двумя Git-ветками с диффом в стиле GitLab (от merge-base)
|
||||
---
|
||||
|
||||
# Eltex Review Heavy
|
||||
|
||||
## Overview
|
||||
|
||||
Тяжелое ревью диффа между двумя Git-ветками в стиле GitLab Merge Request (от merge-base). Запускает полный `/code-review` с кучей агентов.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Пользователь просит "поревьюй ветку feature относительно master" тщательно
|
||||
- Нужен дифф как на GitLab (без лишних изменений из целевой ветки)
|
||||
- Формат вызова: `/el-review-heavy <наша-ветка-с-изменениями> <целевая-ветка>`
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Определи аргументы:
|
||||
- `source` — первая ветка (наша, с изменениями, которую ревьюим)
|
||||
- `target` — вторая ветка (целевая, в которую мерж-реквест)
|
||||
2. Выполни `git fetch origin` — обнови remote refs
|
||||
3. Если текущая checkout-ветка == `source`, выполни `git pull --ff-only origin source` — обнови локальную ветку
|
||||
4. Построй дифф от merge-base: `git diff origin/target...origin/source > /tmp/el-review-heavy.diff` (три точки!)
|
||||
5. Прочитай файл `/tmp/el-review-heavy.diff`
|
||||
6. Запусти скилл `code-review` с этим файлом как аргумент
|
||||
7. Полученные findings переформатируй:
|
||||
- Пронумеруй проблемы
|
||||
- Оставь только критические замечания
|
||||
- Для каждой предложи готовый дифф с исправлением
|
||||
- Объясни простым языком
|
||||
|
||||
## Примеры вызова
|
||||
|
||||
```
|
||||
/el-review-heavy feature main
|
||||
/el-review-heavy my-fix develop
|
||||
/el-review-heavy TASK-123-payment-screen master
|
||||
```
|
||||
|
||||
## Ошибки и крайние случаи
|
||||
|
||||
- Если ветка не существует на remote - сообщи пользователю и не продолжай
|
||||
- Если дифф пустой - сообщи "изменений между ветками нет" и не продолжай
|
||||
- Если аргументы не указаны - попроси уточнить: `/el-review-heavy <source-ветка> <target-ветка>`
|
||||
|
||||
## Формат вывода
|
||||
|
||||
```
|
||||
## Проблема N: [краткое название]
|
||||
|
||||
**Где:** `file.kt:123`
|
||||
|
||||
**Что не так:** простым языком, зачем это плохо
|
||||
|
||||
**Исправление:**
|
||||
```diff
|
||||
- старая строка
|
||||
+ новая строка
|
||||
```
|
||||
```
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
name: el-review
|
||||
description: Use when пользователь запрашивает легкое/быстрое code-review между двумя Git-ветками с диффом в стиле GitLab (от merge-base). Триггеры: "быстрое ревью", "легкое ревью", "/el-review".
|
||||
---
|
||||
|
||||
# Eltex Review
|
||||
|
||||
## Overview
|
||||
|
||||
Лёгкое ревью диффа между двумя Git-ветками в стиле GitLab Merge Request (от merge-base). **Claude делает ревью сам, без multi-agent workflows** — читает дифф и выдаёт только критические проблемы с готовыми исправлениями.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Пользователь просит "поревьюй ветку feature относительно master" быстро
|
||||
- Пользователь говорит "быстрое ревью", "лёгкое ревью", "поверхностное ревью"
|
||||
- Нужен дифф как на GitLab (без лишних изменений из целевой ветки)
|
||||
- Формат вызова: `/el-review <наша-ветка-с-изменениями> <целевая-ветка>`
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Определи аргументы:
|
||||
- `source` — первая ветка (наша, с изменениями, которую ревьюим)
|
||||
- `target` — вторая ветка (целевая, в которую мерж-реквест)
|
||||
2. Выполни `git fetch origin` — обнови remote refs
|
||||
3. Если текущая checkout-ветка == `source`, выполни `git pull --ff-only origin source` — обнови локальную ветку
|
||||
4. Построй дифф от merge-base: `git diff origin/target...origin/source > /tmp/el-review.diff` (три точки!)
|
||||
5. Прочитай файл `/tmp/el-review.diff`
|
||||
6. **Сделай инлайн-ревью сам** — не запускай `/review`, не спавни multi-agent workflows, не делай deep cross-file investigations:
|
||||
- Найди только критические проблемы: баги, утечки, падения, гонки, ошибки в бизнес-логике, нарушения инвариантов
|
||||
- **Не репорти:** форматирование, именование переменных, стиль кода, предложения по рефакторингу (если это не баг)
|
||||
- Для каждой проблемы сразу пиши готовый diff с исправлением
|
||||
- Объясняй кратко, на русском, простым языком
|
||||
- Если критических проблем нет — напиши **«Критических проблем не найдено»** и остановись
|
||||
|
||||
## Примеры вызова
|
||||
|
||||
```
|
||||
/el-review feature main
|
||||
/el-review my-fix develop
|
||||
/el-review TASK-123-payment-screen master
|
||||
```
|
||||
|
||||
## Ошибки и крайние случаи
|
||||
|
||||
- Если ветка не существует на remote - сообщи пользователю и не продолжай
|
||||
- Если дифф пустой - сообщи "изменений между ветками нет" и не продолжай
|
||||
- Если аргументы не указаны - попроси уточнить: `/el-review <source-ветка> <target-ветка>`
|
||||
|
||||
## Формат вывода
|
||||
|
||||
```
|
||||
## Проблема N: [краткое название]
|
||||
|
||||
**Где:** `file.kt:123`
|
||||
|
||||
**Что не так:** простым языком, зачем это плохо
|
||||
|
||||
**Исправление:**
|
||||
```diff
|
||||
- старая строка
|
||||
+ новая строка
|
||||
```
|
||||
```
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
name: switch-account
|
||||
description: Switch to next account or API key (handled by UserPromptSubmit hook, no LLM needed)
|
||||
---
|
||||
|
||||
Переключение аккаунта/ключа уже выполнено хуком до того, как ты это читаешь.
|
||||
Ответь ровно одним символом: `✓`
|
||||
Никаких инструментов. Никаких объяснений. Только `✓`.
|
||||
@@ -94,8 +94,19 @@ fi
|
||||
|
||||
# ── 1. Node.js ───────────────────────────────────────────────
|
||||
info "Проверяю Node.js..."
|
||||
if ! command -v node &>/dev/null; then
|
||||
info "Пытаюсь установить Node.js..."
|
||||
# Хуки (claude-notifier и др.) используют optional chaining (?.) и nullish
|
||||
# coalescing (??) — нужен Node >=18. Проверяем не только наличие node, но и
|
||||
# мажорную версию, иначе системный v12 (Ubuntu 22.04) проходит проверку, а хуки падают.
|
||||
node_major=0
|
||||
if command -v node &>/dev/null; then
|
||||
node_major="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)"
|
||||
fi
|
||||
if [ "${node_major:-0}" -lt 18 ]; then
|
||||
if [ "${node_major:-0}" -gt 0 ]; then
|
||||
info "Найден Node.js v${node_major}, нужен >=18. Обновляю..."
|
||||
else
|
||||
info "Пытаюсь установить Node.js..."
|
||||
fi
|
||||
if command -v brew &>/dev/null; then
|
||||
brew install node
|
||||
elif command -v apt-get &>/dev/null; then
|
||||
@@ -372,40 +383,6 @@ cp "$CONFIG_DIR/global_rules.md" "$HOME/.gemini/GEMINI.md"
|
||||
cp "$CONFIG_DIR/global_rules.md" "$HOME/.cursorrules"
|
||||
success "Native rule-файлы обновлены"
|
||||
|
||||
# ── 6.6. Деплой Claude и Gemini skills ───────────────────────
|
||||
info "Обновляю skills для Claude и Gemini..."
|
||||
SKILLS_SRC="$SCRIPT_DIR/home-configs/claude/skills"
|
||||
CLAUDE_SKILLS_DST="$HOME/.claude/skills"
|
||||
GEMINI_SKILLS_DST="$HOME/.gemini/config/plugins/local-setup/skills"
|
||||
if [ -d "$SKILLS_SRC" ]; then
|
||||
mkdir -p "$CLAUDE_SKILLS_DST" "$GEMINI_SKILLS_DST"
|
||||
|
||||
# Для Gemini нужен plugin.json, чтобы плагин со скилами загрузился
|
||||
GEMINI_PLUGIN_DIR="$HOME/.gemini/config/plugins/local-setup"
|
||||
cat <<EOF > "$GEMINI_PLUGIN_DIR/plugin.json"
|
||||
{
|
||||
"name": "local-setup",
|
||||
"description": "Local custom skills deployed via ai-setup"
|
||||
}
|
||||
EOF
|
||||
|
||||
for skill_dir in "$SKILLS_SRC"/*; do
|
||||
[ -d "$skill_dir" ] || continue
|
||||
skill_name=$(basename "$skill_dir")
|
||||
|
||||
# Деплой для Claude
|
||||
mkdir -p "$CLAUDE_SKILLS_DST/$skill_name"
|
||||
cp -r "$skill_dir/"* "$CLAUDE_SKILLS_DST/$skill_name/"
|
||||
|
||||
# Деплой для Gemini (agy)
|
||||
mkdir -p "$GEMINI_SKILLS_DST/$skill_name"
|
||||
cp -r "$skill_dir/"* "$GEMINI_SKILLS_DST/$skill_name/"
|
||||
done
|
||||
success "Skills обновлены для Claude и Gemini"
|
||||
else
|
||||
info "Папка со skills не найдена, пропускаю"
|
||||
fi
|
||||
|
||||
# ── 6.7. Статусная строка Claude Code ───────────────────────
|
||||
info "Настраиваю статусную строку Claude Code..."
|
||||
STATUSLINE_SRC="$SCRIPT_DIR/home-configs/claude/statusline-command.sh"
|
||||
@@ -557,6 +534,41 @@ else
|
||||
warn "Файл $ADD_HOOK_SRC не найден, пропускаю"
|
||||
fi
|
||||
|
||||
# ── 6.7.3. Хук logout-account ───────────────────────────────────
|
||||
info "Деплою хук logout-account..."
|
||||
LOGOUT_HOOK_SRC="$SCRIPT_DIR/home-configs/claude/hooks/logout-account-hook.sh"
|
||||
LOGOUT_HOOK_DST="$HOME/.claude/hooks/logout-account-hook.sh"
|
||||
mkdir -p "$HOME/.claude/hooks"
|
||||
if [ -f "$LOGOUT_HOOK_SRC" ]; then
|
||||
cp "$LOGOUT_HOOK_SRC" "$LOGOUT_HOOK_DST"
|
||||
chmod +x "$LOGOUT_HOOK_DST"
|
||||
# Прописываем хук в settings.json (идемпотентно)
|
||||
python3 - "$HOME/.claude/settings.json" "$LOGOUT_HOOK_DST" <<'PYEOF'
|
||||
import sys, json, os
|
||||
settings_path, hook_path = sys.argv[1], sys.argv[2]
|
||||
data = {}
|
||||
if os.path.exists(settings_path):
|
||||
with open(settings_path) as f:
|
||||
try: data = json.load(f)
|
||||
except json.JSONDecodeError: pass
|
||||
data.setdefault("hooks", {}).setdefault("UserPromptSubmit", [{"hooks": []}])
|
||||
hook_cmd = f'bash "{hook_path}"'
|
||||
ups = data["hooks"]["UserPromptSubmit"]
|
||||
already = any(
|
||||
any(h.get("command", "") == hook_cmd for h in entry.get("hooks", []))
|
||||
for entry in ups
|
||||
)
|
||||
if not already:
|
||||
ups[0]["hooks"].append({"type": "command", "command": hook_cmd})
|
||||
with open(settings_path, "w") as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
f.write("\n")
|
||||
PYEOF
|
||||
success "Хук logout-account установлен"
|
||||
else
|
||||
warn "Файл $LOGOUT_HOOK_SRC не найден, пропускаю"
|
||||
fi
|
||||
|
||||
# ── 6.8. Регистрация официального маркетплейса плагинов Claude ──
|
||||
info "Настраиваю маркетплейс плагинов Claude Code..."
|
||||
if ! command -v claude &>/dev/null; then
|
||||
@@ -989,16 +1001,16 @@ PYEOF
|
||||
# ai-claude использует ~/.claude/hooks напрямую; остальные лаунчеры получают
|
||||
# свою копию, чтобы /switch-account и /add-account работали изолированно.
|
||||
mkdir -p "$cfg/hooks"
|
||||
for hook in switch-account-hook.sh add-account-hook.sh account-email.sh; do
|
||||
for hook in switch-account-hook.sh add-account-hook.sh logout-account-hook.sh account-email.sh; do
|
||||
if [ -f "$HOME/.claude/hooks/$hook" ]; then
|
||||
cp "$HOME/.claude/hooks/$hook" "$cfg/hooks/$hook"
|
||||
chmod +x "$cfg/hooks/$hook"
|
||||
fi
|
||||
done
|
||||
# Регистрируем UserPromptSubmit хуки в изолированном settings.json
|
||||
python3 - "$cfg/settings.json" "$cfg/hooks/switch-account-hook.sh" "$cfg/hooks/add-account-hook.sh" <<'PYEOF'
|
||||
python3 - "$cfg/settings.json" "$cfg/hooks/switch-account-hook.sh" "$cfg/hooks/add-account-hook.sh" "$cfg/hooks/logout-account-hook.sh" <<'PYEOF'
|
||||
import sys, json, os
|
||||
settings_path, switch_hook, add_hook = sys.argv[1:4]
|
||||
settings_path = sys.argv[1]
|
||||
data = {}
|
||||
if os.path.exists(settings_path):
|
||||
try:
|
||||
@@ -1008,7 +1020,7 @@ if os.path.exists(settings_path):
|
||||
pass
|
||||
data.setdefault("hooks", {}).setdefault("UserPromptSubmit", [{"hooks": []}])
|
||||
ups = data["hooks"]["UserPromptSubmit"]
|
||||
for hook_path in (switch_hook, add_hook):
|
||||
for hook_path in sys.argv[2:]:
|
||||
hook_cmd = f'bash "{hook_path}"'
|
||||
already = any(
|
||||
any(h.get("command", "") == hook_cmd for h in entry.get("hooks", []))
|
||||
|
||||
@@ -188,15 +188,6 @@ test_android_symlink_to_bin_dir() {
|
||||
fi
|
||||
}
|
||||
|
||||
test_android_skill_exists() {
|
||||
skill_file="$(cd "$(dirname "$0")/.." && pwd)/home-configs/claude/skills/android-cli/SKILL.md"
|
||||
if [ -f "$skill_file" ]; then
|
||||
ok "android-cli: custom skill file exists"
|
||||
else
|
||||
fail "android-cli: custom skill file is missing"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── ai-opencode: launches claude with routatic-proxy backend ──────────────────
|
||||
test_opencode_claude_launcher() {
|
||||
if echo "$OPENCODE_SECTION" | grep -q 'claude --dangerously-skip-permissions' \
|
||||
@@ -257,7 +248,6 @@ test_fix7_trap_tmp
|
||||
test_android_cli_install_url
|
||||
test_android_init_called
|
||||
test_android_symlink_to_bin_dir
|
||||
test_android_skill_exists
|
||||
test_opencode_claude_launcher
|
||||
test_opencode_routatic_proxy
|
||||
test_opencode_key_management
|
||||
|
||||
Reference in New Issue
Block a user