feat: extend android tool with category-based action system#46
feat: extend android tool with category-based action system#46KoheiYamashita merged 12 commits intomainfrom
Conversation
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]>
Summary of ChangesHello, 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
🧠 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
Activity
Using Gemini Code AssistThe 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
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 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
|
| val startMillis = try { fmt.parse(startTimeStr)?.time ?: 0L } catch (e: Exception) { | ||
| return ToolResponse(request.requestId, false, error = "Invalid start_time format: ${e.message}") | ||
| } |
There was a problem hiding this comment.
SimpleDateFormat.parse() が null を返した場合の処理に問題があります。
現在、fmt.parse(startTimeStr)?.time ?: 0L というコードでは、パースが成功しても null が返された場合(例:無効な日付だが形式は正しい場合)、startMillis が 0L(エポック時刻)になってしまいます。これにより、意図せず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}")
}
pkg/config/config.go
Outdated
| 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"` |
There was a problem hiding this comment.
設定のJSONタグとカテゴリ名に一貫性がありません。
AndroidCategories 構造体の Web フィールドには json:"web_actions" というタグが付けられていますが、android_actions.go で定義されている対応するカテゴリ名は "web" です。
これにより、config.json ファイルを手動で編集する際に混乱を招く可能性があります。一貫性を保つために、JSONタグをカテゴリ名に合わせて json:"web" に変更することをお勧めします。
| 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"` |
- 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]>
📝 Description
Androidツールをカテゴリベースのモジュールに分割し、設定で有効/無効を切り替え可能にする。
android.goのモノリシックな実装を10カテゴリ(alarm, calendar, contacts, communication, media, navigation, device_control, settings, web, clipboard)に分割ActionHandlerインターフェースによるカテゴリ別ハンドラ委譲config.jsonのcategoriesでカテゴリ単位、disabled_actionsで個別アクション単位の制御🗣️ Type of Change
🔗 Linked Issue
Closes #24
📚 Technical Context (Skip for Docs)
android.goにアクションを追加し続けると肥大化するため、カテゴリ別ファイルに分割。各カテゴリファイルがinit()でregisterCategoryValidatorを呼びバリデータを登録するプラグイン方式を採用。☑️ Checklist
🤖 Generated with Claude Code