Skip to content

feat: extend android tool with category-based action system#46

Merged
KoheiYamashita merged 12 commits intomainfrom
feat/android-tool-categories
Mar 8, 2026
Merged

feat: extend android tool with category-based action system#46
KoheiYamashita merged 12 commits intomainfrom
feat/android-tool-categories

Conversation

@KoheiYamashita
Copy link
Member

📝 Description

Androidツールをカテゴリベースのモジュールに分割し、設定で有効/無効を切り替え可能にする。

  • Go側: android.go のモノリシックな実装を10カテゴリ(alarm, calendar, contacts, communication, media, navigation, device_control, settings, web, clipboard)に分割
  • Kotlin側: ActionHandler インターフェースによるカテゴリ別ハンドラ委譲
  • 設定: config.jsoncategories でカテゴリ単位、disabled_actions で個別アクション単位の制御
  • プライバシー配慮: Contacts / Communication はデフォルト無効

🗣️ Type of Change

  • 🐞 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 📖 Documentation update
  • ⚡ Code refactoring (no functional changes, no api changes)

🔗 Linked Issue

Closes #24

📚 Technical Context (Skip for Docs)

  • Reasoning: 既存の android.go にアクションを追加し続けると肥大化するため、カテゴリ別ファイルに分割。各カテゴリファイルが init()registerCategoryValidator を呼びバリデータを登録するプラグイン方式を採用。

☑️ Checklist

  • My code/docs follow the style of this project.
  • I have performed a self-review of my own changes.
  • I have updated the documentation accordingly.

🤖 Generated with Claude Code

Split monolithic android tool into category-based modules (alarm,
calendar, contacts, communication, media, navigation, device control,
settings, web, clipboard) with per-category enable/disable config.
Privacy-sensitive categories (contacts, communication) default to off.

Closes #24

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

このプルリクエストは、Androidツールをカテゴリベースのモジュールに再構築し、その設定をより柔軟に制御できるようにするものです。これにより、ツールの保守性が向上し、ユーザーは特定の機能の有効/無効を細かく設定できるようになります。また、プライバシーに配慮し、一部のカテゴリはデフォルトで無効化されています。

Highlights

  • Androidツールのモジュール化: モノリシックなAndroidツール実装が、アラーム、カレンダー、連絡先、通信、メディア、ナビゲーション、デバイス制御、設定、ウェブ、クリップボードの10のカテゴリに分割されました。
  • Kotlin側でのアクションハンドリングの委譲: Kotlin側のToolRequestHandlerActionHandlerインターフェースを介してカテゴリ固有のハンドラにアクション処理を委譲するようになりました。
  • 設定によるアクションの制御: config.jsoncategoriesフィールドが追加され、カテゴリ単位での有効/無効切り替えが可能になりました。また、disabled_actionsフィールドで個々のアクションを無効にすることもできます。
  • プライバシー配慮のデフォルト設定: 連絡先と通信カテゴリはデフォルトで無効化されており、ユーザーのプライバシーが考慮されています。
  • 必要なAndroidパーミッションの追加: 新しいカテゴリ機能に対応するため、AndroidManifest.xmlにアラーム、カレンダー、連絡先、位置情報、通知ポリシー、設定書き込みなどのパーミッションが追加されました。
  • Go側でのツール記述の動的生成: Go側のAndroidToolは、有効なカテゴリとアクションに基づいて、その説明とパラメータを動的に生成するようになりました。
  • 設定ファイルのマイグレーション: 新しいAndroidツール設定をサポートするために、設定ファイルのバージョンが3に更新され、既存の設定を新しいスキーマに移行するロジックが追加されました。

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • android/app/src/main/AndroidManifest.xml
    • アラーム、カレンダー、連絡先、位置情報、通知ポリシー、設定書き込みのための新しいパーミッションが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/ToolRequestHandler.kt
    • 新しいアクションハンドラがインポートされました。
    • カテゴリごとのActionHandlerインスタンスのリストが初期化されました。
    • リクエストを適切なActionHandlerに委譲するためのhandlerMapが作成されました。
    • handleメソッドが変更され、不明なアクションを新しいカテゴリベースのハンドラにルーティングするようになりました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/ActionHandler.kt
    • ActionHandlerインターフェースが追加され、supportedActionshandleメソッドが定義されました。
    • ToolRequestからパラメータを抽出するための拡張関数が追加されました。
    • 共通のインテント起動ロジックのためのlaunchActivityヘルパー関数が追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/AlarmActionHandler.kt
    • アラーム関連のアクションを管理するAlarmActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/CalendarActionHandler.kt
    • カレンダー関連のアクションを管理するCalendarActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/ClipboardActionHandler.kt
    • クリップボード関連のアクションを管理するClipboardActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/CommunicationActionHandler.kt
    • 通信関連のアクションを管理するCommunicationActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/ContactsActionHandler.kt
    • 連絡先関連のアクションを管理するContactsActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/DeviceControlActionHandler.kt
    • デバイス制御関連のアクションを管理するDeviceControlActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/MediaActionHandler.kt
    • メディア関連のアクションを管理するMediaActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/NavigationActionHandler.kt
    • ナビゲーション関連のアクションを管理するNavigationActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/SettingsActionHandler.kt
    • 設定関連のアクションを管理するSettingsActionHandlerが追加されました。
  • android/app/src/main/java/io/clawdroid/assistant/actions/WebActionHandler.kt
    • ウェブ関連のアクションを管理するWebActionHandlerが追加されました。
  • pkg/agent/loop.go
    • NewAndroidToolの呼び出しが更新され、Androidツール設定を渡すようになりました。
  • pkg/config/config.go
    • 各カテゴリのブール値を定義するAndroidCategories構造体が追加されました。
    • AndroidToolsConfigCategoriesDisabledActionsを含むように変更されました。
    • DefaultConfigが新しいAndroidCategoriesをデフォルト値(連絡先と通信は無効)で初期化するように更新されました。
  • pkg/config/migration.go
    • ConfigVersionが3にインクリメントされました。
    • 新しいAndroidカテゴリのデフォルト値を設定するためのmigrateV2ToV3関数が追加されました。
  • pkg/config/migration_test.go
    • 新しいマイグレーションロジックを検証するためのTestMigrateConfig_FromV2ToV3が追加されました。
    • TestLoadConfig_NoMigrationWhenCurrentversion: 3を使用するように更新されました。
  • pkg/tools/android.go
    • configパッケージがインポートされました。
    • NewAndroidToolconfig.AndroidToolsConfigを受け入れるように変更されました。
    • ハードコードされたuiActionsマップが削除されました。
    • Description()およびParameters()メソッドが、有効なアクションとクライアントタイプに基づいて動的に構築されるように更新されました。
    • ExecuteメソッドにisActionEnabledチェックが追加されました。
    • カテゴリ固有のパラメータ検証のためにcategoryValidatorsマップとregisterCategoryValidator関数が導入されました。
    • パラメータ解析のためのヘルパー関数toInttoStringtoBoolが追加されました。
  • pkg/tools/android_actions.go
    • ツールアクションとそのパラメータを定義するandroidActionおよびandroidParam構造体が追加されました。
    • サポートされるすべてのAndroidアクション、そのカテゴリ、説明、およびパラメータを含むallActions配列が定義されました。
    • 効率的なルックアップのためにactionCategoryMapuiActionMapが導入されました。
    • 設定とクライアントタイプに基づいてアクションをフィルタリングするenabledActions関数が追加されました。
    • カテゴリが有効かどうかをチェックするisCategoryEnabled関数が追加されました。
    • ツールメタデータを動的に生成するbuildDescriptionおよびbuildParameters関数が追加されました。
  • pkg/tools/android_alarm.go
    • アラーム関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • アラームアクション固有のパラメータ検証のためのvalidateAlarmParams関数が追加されました。
  • pkg/tools/android_calendar.go
    • カレンダー関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • カレンダーアクション固有のパラメータ検証のためのvalidateCalendarParams関数が追加されました。
  • pkg/tools/android_clipboard.go
    • クリップボード関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • クリップボードアクション固有のパラメータ検証のためのvalidateClipboardParams関数が追加されました。
  • pkg/tools/android_communication.go
    • 通信関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • 通信アクション固有のパラメータ検証のためのvalidateCommunicationParams関数が追加されました。
  • pkg/tools/android_contacts.go
    • 連絡先関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • 連絡先アクション固有のパラメータ検証のためのvalidateContactsParams関数が追加されました。
  • pkg/tools/android_device_control.go
    • デバイス制御関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • デバイス制御アクション固有のパラメータ検証のためのvalidateDeviceControlParams関数が追加されました。
  • pkg/tools/android_media.go
    • メディア関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • メディアアクション固有のパラメータ検証のためのvalidateMediaParams関数が追加されました。
  • pkg/tools/android_navigation.go
    • ナビゲーション関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • ナビゲーションアクション固有のパラメータ検証のためのvalidateNavigationParams関数が追加されました。
  • pkg/tools/android_settings.go
    • 設定関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • 設定アクション固有のパラメータ検証のためのvalidateSettingsParams関数が追加されました。
  • pkg/tools/android_web.go
    • ウェブ関連のアクションをcategoryValidatorsに登録するためのinit関数が追加されました。
    • ウェブアクション固有のパラメータ検証のためのvalidateWebParams関数が追加されました。
Activity
  • このプルリクエストはClaude Codeによって生成されました。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

これは大規模かつ優れたリファクタリングです。モノリシックだった android ツールが、GoとKotlinの両サイドでモジュール化されたカテゴリベースのシステムにうまく分割されています。Goでの init() 関数による登録や、Kotlinでの ActionHandler インターフェースの使用は、将来的に新しいアクションを追加するのを容易にする素晴らしい設計判断です。コードは全体的に高品質です。一貫性を改善し、潜在的なバグを修正するための提案がいくつかあります。

Comment on lines +44 to +46
val startMillis = try { fmt.parse(startTimeStr)?.time ?: 0L } catch (e: Exception) {
return ToolResponse(request.requestId, false, error = "Invalid start_time format: ${e.message}")
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

SimpleDateFormat.parse()null を返した場合の処理に問題があります。

現在、fmt.parse(startTimeStr)?.time ?: 0L というコードでは、パースが成功しても null が返された場合(例:無効な日付だが形式は正しい場合)、startMillis0L(エポック時刻)になってしまいます。これにより、意図せず1970年のイベントが作成される可能性があります。

null が返された場合は、無効な入力としてエラーを返すように修正することをお勧めします。同様の問題が handleQueryEvents の77行目と80行目にも存在します。

        val startMillis = try {
            fmt.parse(startTimeStr)?.time
                ?: return ToolResponse(request.requestId, false, error = "Invalid start_time format: could not parse date")
        } catch (e: Exception) {
            return ToolResponse(request.requestId, false, error = "Invalid start_time format: ${e.message}")
        }

Navigation bool `json:"navigation" label:"Navigation" env:"CLAWDROID_TOOLS_ANDROID_NAVIGATION"`
DeviceControl bool `json:"device_control" label:"Device Control" env:"CLAWDROID_TOOLS_ANDROID_DEVICE_CONTROL"`
Settings bool `json:"settings" label:"Settings" env:"CLAWDROID_TOOLS_ANDROID_SETTINGS"`
Web bool `json:"web_actions" label:"Web Actions" env:"CLAWDROID_TOOLS_ANDROID_WEB"`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

設定のJSONタグとカテゴリ名に一貫性がありません。

AndroidCategories 構造体の Web フィールドには json:"web_actions" というタグが付けられていますが、android_actions.go で定義されている対応するカテゴリ名は "web" です。

これにより、config.json ファイルを手動で編集する際に混乱を招く可能性があります。一貫性を保つために、JSONタグをカテゴリ名に合わせて json:"web" に変更することをお勧めします。

Suggested change
Web bool `json:"web_actions" label:"Web Actions" env:"CLAWDROID_TOOLS_ANDROID_WEB"`
Web bool `json:"web" label:"Web Actions" env:"CLAWDROID_TOOLS_ANDROID_WEB"`

KoheiYamashita and others added 11 commits March 8, 2026 16:09
- Merge duplicate parameter descriptions in buildParameters (#1)
- Use map for DisabledActions lookup in isActionEnabled (#2)
- Add URL scheme whitelist (http/https only) for open_url (#3)
- Escape SQL LIKE wildcards in ContactsActionHandler (#4)
- Fix JSON tag inconsistency: web_actions -> web (#5)
- Add comprehensive tests for android tool (#6)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace the DisabledActions string slice with typed action structs
(AlarmActions, CalendarActions, etc.) grouped under AndroidActions.
Each action is now a bool field with a label tag, so the schema system
auto-generates individual toggles in the settings UI.

- Add 10 category action structs + AndroidActions wrapper to config
- Update migrateV2ToV3 to convert old DisabledActions to new struct
- Add depth field to SchemaField for hierarchical UI rendering
- Hide DisabledActions from UI via empty label tag
- Update Android app to use depth-based indentation in config screen

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Merge the separate Categories/Actions structure into unified category
wrappers (e.g. AlarmCategory with Enabled + Actions). This makes each
category toggle and its actions appear together in the settings UI with
proper depth-based hierarchy.

Android UI now disables child action toggles when the parent category
is turned off, providing clear visual feedback.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
When the top-level "Enabled" toggle (e.g. Android tool) is turned off,
all child categories and actions are now greyed out in the settings UI.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
The section-level "Enabled" field (e.g. android.enabled) has a non-empty
group ("Android"), so the previous group.isEmpty() check never matched.
Use depth <= 1 to identify section toggles and depth > 1 for category
toggles.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add permission checking/requesting before ActionHandler execution so
users see permission dialogs instead of SecurityException errors.
Runtime permissions (calendar, contacts, location) use PermissionRequester
with suspendCancellableCoroutine to await the dialog result. Special
permissions (DND, write settings) open the settings screen with an error
message since they cannot be awaited programmatically.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace the Intent-based calendar event creation (which opens the
calendar app's add screen) with direct ContentResolver.insert() for
consistency with update_event, delete_event, and add_reminder.
Automatically selects the primary or first writable calendar as default.
WRITE_CALENDAR permission is now required and requested via the
permission dialog.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Allow users to choose which calendar to use for write actions
(create_event, update_event, add_reminder) instead of always
auto-detecting the primary calendar. On first use without a
configured calendar, a picker dialog is shown and the selection
is saved to config. The setting is also editable from the
config UI.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…r with Compose

Remove runtime config mutation (saveCalendarIdToConfig) from
CalendarActionHandler — calendar_id is now a value copy from config,
changed via settings screen and reflected on restart. Replace
android.app.AlertDialog in CalendarPickerActivity with Compose
AlertDialog using ClawDroidTheme colors.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
When calendar_id is empty, the picker launches every write action.
The label should reflect this behavior instead of implying auto-detection.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ening

- Add phone number and email validation (Go + Kotlin) to reject injection attempts
- Validate intent extras to only allow primitive types (reject nested maps/arrays)
- Return error for invalid settings sections instead of silent fallback
- Add URL scheme validation (http/https only) in WebActionHandler
- Fix BroadcastReceiver double-unregister race with AtomicBoolean guard
- Add comprehensive tests for all new validations

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@KoheiYamashita KoheiYamashita enabled auto-merge (squash) March 8, 2026 14:20
@KoheiYamashita KoheiYamashita disabled auto-merge March 8, 2026 14:20
@KoheiYamashita KoheiYamashita merged commit ebeee24 into main Mar 8, 2026
16 checks passed
@KoheiYamashita KoheiYamashita deleted the feat/android-tool-categories branch March 8, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Androidツール拡張

1 participant